mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-01 07:15:39 -04:00
Merge branch 'bt-16' into '1.6'
[1.6] bluez5: backport fixes to 1.6 branch See merge request pipewire/pipewire!2769
This commit is contained in:
commit
d090fc3ea3
7 changed files with 138 additions and 198 deletions
|
|
@ -1375,9 +1375,9 @@ Default: as per QoS preset.
|
||||||
|
|
||||||
@PAR@ device-prop bluez5.bap.force-target-latency = "balanced" # string
|
@PAR@ device-prop bluez5.bap.force-target-latency = "balanced" # string
|
||||||
BAP QoS target latency profile forced for QoS configuration selection.
|
BAP QoS target latency profile forced for QoS configuration selection.
|
||||||
If not set or set to "balanced", both low-latency and high-reliabilty QoS configuration table are used.
|
If not set or set to "balanced", both low-latency and high-reliability QoS configuration table are used.
|
||||||
This property is experimental.
|
This property is experimental.
|
||||||
Available: low-latency, high-reliabilty, balanced
|
Available: low-latency, high-reliability, balanced
|
||||||
|
|
||||||
## Node properties
|
## Node properties
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,8 @@ static int codec_fill_caps(const struct media_codec *codec, uint32_t flags,
|
||||||
|
|
||||||
static const struct media_codec_config
|
static const struct media_codec_config
|
||||||
aac_frequencies[] = {
|
aac_frequencies[] = {
|
||||||
{ AAC_SAMPLING_FREQ_48000, 48000, 11 },
|
|
||||||
{ AAC_SAMPLING_FREQ_44100, 44100, 10 },
|
{ AAC_SAMPLING_FREQ_44100, 44100, 10 },
|
||||||
|
{ AAC_SAMPLING_FREQ_48000, 48000, 11 },
|
||||||
{ AAC_SAMPLING_FREQ_96000, 96000, 9 },
|
{ AAC_SAMPLING_FREQ_96000, 96000, 9 },
|
||||||
{ AAC_SAMPLING_FREQ_88200, 88200, 8 },
|
{ AAC_SAMPLING_FREQ_88200, 88200, 8 },
|
||||||
{ AAC_SAMPLING_FREQ_64000, 64000, 7 },
|
{ AAC_SAMPLING_FREQ_64000, 64000, 7 },
|
||||||
|
|
@ -194,75 +194,6 @@ static int codec_select_config(const struct media_codec *codec, uint32_t flags,
|
||||||
return sizeof(conf);
|
return sizeof(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
|
|
||||||
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
|
|
||||||
struct spa_pod_builder *b, struct spa_pod **param)
|
|
||||||
{
|
|
||||||
a2dp_aac_t conf;
|
|
||||||
struct spa_pod_frame f[2];
|
|
||||||
struct spa_pod_choice *choice;
|
|
||||||
uint32_t position[2];
|
|
||||||
uint32_t i = 0;
|
|
||||||
|
|
||||||
if (caps_size < sizeof(conf))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
memcpy(&conf, caps, sizeof(conf));
|
|
||||||
|
|
||||||
if (idx > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
spa_pod_builder_push_object(b, &f[0], SPA_TYPE_OBJECT_Format, id);
|
|
||||||
spa_pod_builder_add(b,
|
|
||||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
|
||||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
|
||||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_S16),
|
|
||||||
0);
|
|
||||||
spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_rate, 0);
|
|
||||||
|
|
||||||
spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_None, 0);
|
|
||||||
choice = (struct spa_pod_choice*)spa_pod_builder_frame(b, &f[1]);
|
|
||||||
i = 0;
|
|
||||||
SPA_FOR_EACH_ELEMENT_VAR(aac_frequencies, f) {
|
|
||||||
if (AAC_GET_FREQUENCY(conf) & f->config) {
|
|
||||||
if (i++ == 0)
|
|
||||||
spa_pod_builder_int(b, f->value);
|
|
||||||
spa_pod_builder_int(b, f->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i > 1)
|
|
||||||
choice->body.type = SPA_CHOICE_Enum;
|
|
||||||
spa_pod_builder_pop(b, &f[1]);
|
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (SPA_FLAG_IS_SET(conf.channels, AAC_CHANNELS_1 | AAC_CHANNELS_2)) {
|
|
||||||
spa_pod_builder_add(b,
|
|
||||||
SPA_FORMAT_AUDIO_channels, SPA_POD_CHOICE_RANGE_Int(2, 1, 2),
|
|
||||||
0);
|
|
||||||
} else if (conf.channels & AAC_CHANNELS_1) {
|
|
||||||
position[0] = SPA_AUDIO_CHANNEL_MONO;
|
|
||||||
spa_pod_builder_add(b,
|
|
||||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(1),
|
|
||||||
SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t),
|
|
||||||
SPA_TYPE_Id, 1, position),
|
|
||||||
0);
|
|
||||||
} else if (conf.channels & AAC_CHANNELS_2) {
|
|
||||||
position[0] = SPA_AUDIO_CHANNEL_FL;
|
|
||||||
position[1] = SPA_AUDIO_CHANNEL_FR;
|
|
||||||
spa_pod_builder_add(b,
|
|
||||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(2),
|
|
||||||
SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t),
|
|
||||||
SPA_TYPE_Id, 2, position),
|
|
||||||
0);
|
|
||||||
} else
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
*param = spa_pod_builder_pop(b, &f[0]);
|
|
||||||
return *param == NULL ? -EIO : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int codec_validate_config(const struct media_codec *codec, uint32_t flags,
|
static int codec_validate_config(const struct media_codec *codec, uint32_t flags,
|
||||||
const void *caps, size_t caps_size,
|
const void *caps, size_t caps_size,
|
||||||
struct spa_audio_info *info)
|
struct spa_audio_info *info)
|
||||||
|
|
@ -283,8 +214,10 @@ static int codec_validate_config(const struct media_codec *codec, uint32_t flags
|
||||||
/*
|
/*
|
||||||
* A2DP v1.3.2, 4.5.2: only one bit shall be set in bitfields.
|
* A2DP v1.3.2, 4.5.2: only one bit shall be set in bitfields.
|
||||||
* However, there is a report (#1342) of device setting multiple
|
* However, there is a report (#1342) of device setting multiple
|
||||||
* bits for AAC object type. It's not clear if this was due to
|
* bits for AAC object type. In addition AirPods set multiple bits.
|
||||||
* a BlueZ bug, but we can be lax here and below in codec_init.
|
*
|
||||||
|
* Some devices also set multiple bits in frequencies & channels.
|
||||||
|
* For these, pick a "preferred" choice.
|
||||||
*/
|
*/
|
||||||
if (!(conf.object_type & (AAC_OBJECT_TYPE_MPEG2_AAC_LC |
|
if (!(conf.object_type & (AAC_OBJECT_TYPE_MPEG2_AAC_LC |
|
||||||
AAC_OBJECT_TYPE_MPEG4_AAC_LC |
|
AAC_OBJECT_TYPE_MPEG4_AAC_LC |
|
||||||
|
|
@ -315,6 +248,35 @@ static int codec_validate_config(const struct media_codec *codec, uint32_t flags
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
|
||||||
|
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
|
||||||
|
struct spa_pod_builder *b, struct spa_pod **param)
|
||||||
|
{
|
||||||
|
struct spa_audio_info info;
|
||||||
|
struct spa_pod_frame f[1];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if ((res = codec_validate_config(codec, flags, caps, caps_size, &info)) < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (idx > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
spa_pod_builder_push_object(b, &f[0], SPA_TYPE_OBJECT_Format, id);
|
||||||
|
spa_pod_builder_add(b,
|
||||||
|
SPA_FORMAT_mediaType, SPA_POD_Id(info.media_type),
|
||||||
|
SPA_FORMAT_mediaSubtype, SPA_POD_Id(info.media_subtype),
|
||||||
|
SPA_FORMAT_AUDIO_format, SPA_POD_Id(info.info.raw.format),
|
||||||
|
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info.info.raw.rate),
|
||||||
|
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info.info.raw.channels),
|
||||||
|
SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t),
|
||||||
|
SPA_TYPE_Id, info.info.raw.channels, info.info.raw.position),
|
||||||
|
0);
|
||||||
|
|
||||||
|
*param = spa_pod_builder_pop(b, &f[0]);
|
||||||
|
return *param == NULL ? -EIO : 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void *codec_init_props(const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings)
|
static void *codec_init_props(const struct media_codec *codec, uint32_t flags, const struct spa_dict *settings)
|
||||||
{
|
{
|
||||||
struct props *p = calloc(1, sizeof(struct props));
|
struct props *p = calloc(1, sizeof(struct props));
|
||||||
|
|
@ -369,14 +331,14 @@ static void *codec_init(const struct media_codec *codec, uint32_t flags,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* If object type has multiple bits set (invalid per spec, see above),
|
/* If object type has multiple bits set (invalid per spec, see above),
|
||||||
* assume the device usually means AAC-LC.
|
* assume the device usually means MPEG2 AAC LC which is mandatory.
|
||||||
*/
|
*/
|
||||||
if (conf->object_type & AAC_OBJECT_TYPE_MPEG4_AAC_LC) {
|
if (conf->object_type & AAC_OBJECT_TYPE_MPEG2_AAC_LC) {
|
||||||
res = aacEncoder_SetParam(this->aacenc, AACENC_AOT, AOT_AAC_LC);
|
res = aacEncoder_SetParam(this->aacenc, AACENC_AOT, AOT_MP2_AAC_LC);
|
||||||
if (res != AACENC_OK)
|
if (res != AACENC_OK)
|
||||||
goto error;
|
goto error;
|
||||||
} else if (conf->object_type & AAC_OBJECT_TYPE_MPEG2_AAC_LC) {
|
} else if (conf->object_type & AAC_OBJECT_TYPE_MPEG4_AAC_LC) {
|
||||||
res = aacEncoder_SetParam(this->aacenc, AACENC_AOT, AOT_MP2_AAC_LC);
|
res = aacEncoder_SetParam(this->aacenc, AACENC_AOT, AOT_AAC_LC);
|
||||||
if (res != AACENC_OK)
|
if (res != AACENC_OK)
|
||||||
goto error;
|
goto error;
|
||||||
} else if (conf->object_type & AAC_OBJECT_TYPE_MPEG4_AAC_ELD) {
|
} else if (conf->object_type & AAC_OBJECT_TYPE_MPEG4_AAC_ELD) {
|
||||||
|
|
|
||||||
|
|
@ -343,77 +343,27 @@ static int codec_enum_config(const struct media_codec *codec, uint32_t flags,
|
||||||
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
|
const void *caps, size_t caps_size, uint32_t id, uint32_t idx,
|
||||||
struct spa_pod_builder *b, struct spa_pod **param)
|
struct spa_pod_builder *b, struct spa_pod **param)
|
||||||
{
|
{
|
||||||
a2dp_sbc_t conf;
|
struct spa_audio_info info;
|
||||||
struct spa_pod_frame f[2];
|
struct spa_pod_frame f[1];
|
||||||
struct spa_pod_choice *choice;
|
int res;
|
||||||
uint32_t i = 0;
|
|
||||||
uint32_t position[2];
|
|
||||||
|
|
||||||
if (caps_size < sizeof(conf))
|
if ((res = codec_validate_config(codec, flags, caps, caps_size, &info)) < 0)
|
||||||
return -EINVAL;
|
return res;
|
||||||
|
|
||||||
memcpy(&conf, caps, sizeof(conf));
|
|
||||||
|
|
||||||
if (idx > 0)
|
if (idx > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spa_pod_builder_push_object(b, &f[0], SPA_TYPE_OBJECT_Format, id);
|
spa_pod_builder_push_object(b, &f[0], SPA_TYPE_OBJECT_Format, id);
|
||||||
spa_pod_builder_add(b,
|
spa_pod_builder_add(b,
|
||||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
SPA_FORMAT_mediaType, SPA_POD_Id(info.media_type),
|
||||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
SPA_FORMAT_mediaSubtype, SPA_POD_Id(info.media_subtype),
|
||||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_S16),
|
SPA_FORMAT_AUDIO_format, SPA_POD_Id(info.info.raw.format),
|
||||||
|
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info.info.raw.rate),
|
||||||
|
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info.info.raw.channels),
|
||||||
|
SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t),
|
||||||
|
SPA_TYPE_Id, info.info.raw.channels, info.info.raw.position),
|
||||||
0);
|
0);
|
||||||
spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_rate, 0);
|
|
||||||
|
|
||||||
spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_None, 0);
|
|
||||||
choice = (struct spa_pod_choice*)spa_pod_builder_frame(b, &f[1]);
|
|
||||||
i = 0;
|
|
||||||
if (conf.frequency & SBC_SAMPLING_FREQ_48000) {
|
|
||||||
if (i++ == 0)
|
|
||||||
spa_pod_builder_int(b, 48000);
|
|
||||||
spa_pod_builder_int(b, 48000);
|
|
||||||
}
|
|
||||||
if (conf.frequency & SBC_SAMPLING_FREQ_44100) {
|
|
||||||
if (i++ == 0)
|
|
||||||
spa_pod_builder_int(b, 44100);
|
|
||||||
spa_pod_builder_int(b, 44100);
|
|
||||||
}
|
|
||||||
if (conf.frequency & SBC_SAMPLING_FREQ_32000) {
|
|
||||||
if (i++ == 0)
|
|
||||||
spa_pod_builder_int(b, 32000);
|
|
||||||
spa_pod_builder_int(b, 32000);
|
|
||||||
}
|
|
||||||
if (conf.frequency & SBC_SAMPLING_FREQ_16000) {
|
|
||||||
if (i++ == 0)
|
|
||||||
spa_pod_builder_int(b, 16000);
|
|
||||||
spa_pod_builder_int(b, 16000);
|
|
||||||
}
|
|
||||||
if (i > 1)
|
|
||||||
choice->body.type = SPA_CHOICE_Enum;
|
|
||||||
spa_pod_builder_pop(b, &f[1]);
|
|
||||||
|
|
||||||
if (conf.channel_mode & SBC_CHANNEL_MODE_MONO &&
|
|
||||||
conf.channel_mode & (SBC_CHANNEL_MODE_JOINT_STEREO |
|
|
||||||
SBC_CHANNEL_MODE_STEREO | SBC_CHANNEL_MODE_DUAL_CHANNEL)) {
|
|
||||||
spa_pod_builder_add(b,
|
|
||||||
SPA_FORMAT_AUDIO_channels, SPA_POD_CHOICE_RANGE_Int(2, 1, 2),
|
|
||||||
0);
|
|
||||||
} else if (conf.channel_mode & SBC_CHANNEL_MODE_MONO) {
|
|
||||||
position[0] = SPA_AUDIO_CHANNEL_MONO;
|
|
||||||
spa_pod_builder_add(b,
|
|
||||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(1),
|
|
||||||
SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t),
|
|
||||||
SPA_TYPE_Id, 1, position),
|
|
||||||
0);
|
|
||||||
} else {
|
|
||||||
position[0] = SPA_AUDIO_CHANNEL_FL;
|
|
||||||
position[1] = SPA_AUDIO_CHANNEL_FR;
|
|
||||||
spa_pod_builder_add(b,
|
|
||||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(2),
|
|
||||||
SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t),
|
|
||||||
SPA_TYPE_Id, 2, position),
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
*param = spa_pod_builder_pop(b, &f[0]);
|
*param = spa_pod_builder_pop(b, &f[0]);
|
||||||
return *param == NULL ? -EIO : 1;
|
return *param == NULL ? -EIO : 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1969,6 +1969,9 @@ static void hfp_hf_remove_disconnected_calls(struct rfcomm *rfcomm)
|
||||||
struct updated_call *updated_call;
|
struct updated_call *updated_call;
|
||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
|
if (!rfcomm->telephony_ag)
|
||||||
|
return;
|
||||||
|
|
||||||
spa_list_for_each_safe(call, call_tmp, &rfcomm->telephony_ag->call_list, link) {
|
spa_list_for_each_safe(call, call_tmp, &rfcomm->telephony_ag->call_list, link) {
|
||||||
found = false;
|
found = false;
|
||||||
spa_list_for_each(updated_call, &rfcomm->updated_call_list, link) {
|
spa_list_for_each(updated_call, &rfcomm->updated_call_list, link) {
|
||||||
|
|
@ -2097,6 +2100,8 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
|
||||||
|
|
||||||
if (spa_streq(rfcomm->hf_indicators[indicator], "battchg")) {
|
if (spa_streq(rfcomm->hf_indicators[indicator], "battchg")) {
|
||||||
spa_bt_device_report_battery_level(rfcomm->device, value * 100 / 5);
|
spa_bt_device_report_battery_level(rfcomm->device, value * 100 / 5);
|
||||||
|
} else if (!rfcomm->telephony_ag) {
|
||||||
|
/* noop */
|
||||||
} else if (spa_streq(rfcomm->hf_indicators[indicator], "callsetup")) {
|
} else if (spa_streq(rfcomm->hf_indicators[indicator], "callsetup")) {
|
||||||
if (rfcomm->hfp_hf_clcc) {
|
if (rfcomm->hfp_hf_clcc) {
|
||||||
rfcomm_send_cmd(rfcomm, hfp_hf_clcc_update, NULL, "AT+CLCC");
|
rfcomm_send_cmd(rfcomm, hfp_hf_clcc_update, NULL, "AT+CLCC");
|
||||||
|
|
@ -2245,7 +2250,8 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
|
||||||
rfcomm->hfp_hf_in_progress = false;
|
rfcomm->hfp_hf_in_progress = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sscanf(token, "+CLIP: \"%16[^\"]\",%u", number, &type) == 2) {
|
} else if (sscanf(token, "+CLIP: \"%16[^\"]\",%u", number, &type) == 2
|
||||||
|
&& rfcomm->telephony_ag) {
|
||||||
struct spa_bt_telephony_call *call;
|
struct spa_bt_telephony_call *call;
|
||||||
spa_list_for_each(call, &rfcomm->telephony_ag->call_list, link) {
|
spa_list_for_each(call, &rfcomm->telephony_ag->call_list, link) {
|
||||||
if (call->state == CALL_STATE_INCOMING && !spa_streq(number, call->line_identification)) {
|
if (call->state == CALL_STATE_INCOMING && !spa_streq(number, call->line_identification)) {
|
||||||
|
|
@ -2256,7 +2262,8 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sscanf(token, "+CCWA: \"%16[^\"]\",%u", number, &type) == 2) {
|
} else if (sscanf(token, "+CCWA: \"%16[^\"]\",%u", number, &type) == 2
|
||||||
|
&& rfcomm->telephony_ag) {
|
||||||
struct spa_bt_telephony_call *call;
|
struct spa_bt_telephony_call *call;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
|
|
@ -2273,7 +2280,7 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
|
||||||
if (call == NULL)
|
if (call == NULL)
|
||||||
spa_log_warn(backend->log, "failed to create waiting call");
|
spa_log_warn(backend->log, "failed to create waiting call");
|
||||||
}
|
}
|
||||||
} else if (spa_strstartswith(token, "+CLCC:")) {
|
} else if (spa_strstartswith(token, "+CLCC:") && rfcomm->telephony_ag) {
|
||||||
struct spa_bt_telephony_call *call;
|
struct spa_bt_telephony_call *call;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
char *token_end;
|
char *token_end;
|
||||||
|
|
@ -2421,17 +2428,19 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rfcomm->telephony_ag = telephony_ag_new(backend->telephony, 0);
|
if (backend->telephony) {
|
||||||
rfcomm->telephony_ag->address = strdup(rfcomm->device->address);
|
rfcomm->telephony_ag = telephony_ag_new(backend->telephony, 0);
|
||||||
rfcomm->telephony_ag->volume[SPA_BT_VOLUME_ID_RX] = rfcomm->volumes[SPA_BT_VOLUME_ID_RX].hw_volume = backend->hfp_default_speaker_volume;
|
rfcomm->telephony_ag->address = strdup(rfcomm->device->address);
|
||||||
rfcomm->telephony_ag->volume[SPA_BT_VOLUME_ID_TX] = rfcomm->volumes[SPA_BT_VOLUME_ID_TX].hw_volume = backend->hfp_default_mic_volume;
|
rfcomm->telephony_ag->volume[SPA_BT_VOLUME_ID_RX] = rfcomm->volumes[SPA_BT_VOLUME_ID_RX].hw_volume = backend->hfp_default_speaker_volume;
|
||||||
telephony_ag_set_callbacks(rfcomm->telephony_ag,
|
rfcomm->telephony_ag->volume[SPA_BT_VOLUME_ID_TX] = rfcomm->volumes[SPA_BT_VOLUME_ID_TX].hw_volume = backend->hfp_default_mic_volume;
|
||||||
|
telephony_ag_set_callbacks(rfcomm->telephony_ag,
|
||||||
&telephony_ag_callbacks, rfcomm);
|
&telephony_ag_callbacks, rfcomm);
|
||||||
if (rfcomm->transport) {
|
if (rfcomm->transport) {
|
||||||
rfcomm->telephony_ag->transport.codec = rfcomm->transport->media_codec->codec_id;
|
rfcomm->telephony_ag->transport.codec = rfcomm->transport->media_codec->codec_id;
|
||||||
rfcomm->telephony_ag->transport.state = rfcomm->transport->state;
|
rfcomm->telephony_ag->transport.state = rfcomm->transport->state;
|
||||||
|
}
|
||||||
|
telephony_ag_register(rfcomm->telephony_ag);
|
||||||
}
|
}
|
||||||
telephony_ag_register(rfcomm->telephony_ag);
|
|
||||||
|
|
||||||
rfcomm_send_cmd(rfcomm, hfp_hf_clip, NULL, "AT+CLIP=1");
|
rfcomm_send_cmd(rfcomm, hfp_hf_clip, NULL, "AT+CLIP=1");
|
||||||
break;
|
break;
|
||||||
|
|
@ -2478,7 +2487,7 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
|
||||||
break;
|
break;
|
||||||
case hfp_hf_chld1_hangup:
|
case hfp_hf_chld1_hangup:
|
||||||
/* For HFP/HF/TWC/BV-03-C - see 0e92ab9307e05758b3f70b4c0648e29c1d1e50be */
|
/* For HFP/HF/TWC/BV-03-C - see 0e92ab9307e05758b3f70b4c0648e29c1d1e50be */
|
||||||
if (!rfcomm->hfp_hf_clcc) {
|
if (!rfcomm->hfp_hf_clcc && rfcomm->telephony_ag) {
|
||||||
struct spa_bt_telephony_call *call, *tcall;
|
struct spa_bt_telephony_call *call, *tcall;
|
||||||
spa_list_for_each_safe(call, tcall, &rfcomm->telephony_ag->call_list, link) {
|
spa_list_for_each_safe(call, tcall, &rfcomm->telephony_ag->call_list, link) {
|
||||||
if (call->state == CALL_STATE_ACTIVE) {
|
if (call->state == CALL_STATE_ACTIVE) {
|
||||||
|
|
|
||||||
|
|
@ -126,22 +126,22 @@ static const struct bap_qos bap_qos_configs[] = {
|
||||||
BAP_QOS("48_6_1", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 155, 5, 20, 40000, 27, "low-latency"), /* 48_6_1 */
|
BAP_QOS("48_6_1", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 155, 5, 20, 40000, 27, "low-latency"), /* 48_6_1 */
|
||||||
|
|
||||||
/* BAP v1.0.1 Table 5.2; high-reliability */
|
/* BAP v1.0.1 Table 5.2; high-reliability */
|
||||||
BAP_QOS("8_1_2", LC3_CONFIG_FREQ_8KHZ, LC3_CONFIG_DURATION_7_5, false, 26, 13, 75, 40000, 10, "high-reliabilty"), /* 8_1_2 */
|
BAP_QOS("8_1_2", LC3_CONFIG_FREQ_8KHZ, LC3_CONFIG_DURATION_7_5, false, 26, 13, 75, 40000, 10, "high-reliability"), /* 8_1_2 */
|
||||||
BAP_QOS("8_2_2", LC3_CONFIG_FREQ_8KHZ, LC3_CONFIG_DURATION_10, false, 30, 13, 95, 40000, 0, "high-reliabilty"), /* 8_2_2 */
|
BAP_QOS("8_2_2", LC3_CONFIG_FREQ_8KHZ, LC3_CONFIG_DURATION_10, false, 30, 13, 95, 40000, 0, "high-reliability"), /* 8_2_2 */
|
||||||
BAP_QOS("16_1_2", LC3_CONFIG_FREQ_16KHZ, LC3_CONFIG_DURATION_7_5, false, 30, 13, 75, 40000, 11, "high-reliabilty"), /* 16_1_2 */
|
BAP_QOS("16_1_2", LC3_CONFIG_FREQ_16KHZ, LC3_CONFIG_DURATION_7_5, false, 30, 13, 75, 40000, 11, "high-reliability"), /* 16_1_2 */
|
||||||
BAP_QOS("16_2_2", LC3_CONFIG_FREQ_16KHZ, LC3_CONFIG_DURATION_10, false, 40, 13, 95, 40000, 1, "high-reliabilty"), /* 16_2_2 */
|
BAP_QOS("16_2_2", LC3_CONFIG_FREQ_16KHZ, LC3_CONFIG_DURATION_10, false, 40, 13, 95, 40000, 1, "high-reliability"), /* 16_2_2 */
|
||||||
BAP_QOS("24_1_2", LC3_CONFIG_FREQ_24KHZ, LC3_CONFIG_DURATION_7_5, false, 45, 13, 75, 40000, 12, "high-reliabilty"), /* 24_1_2 */
|
BAP_QOS("24_1_2", LC3_CONFIG_FREQ_24KHZ, LC3_CONFIG_DURATION_7_5, false, 45, 13, 75, 40000, 12, "high-reliability"), /* 24_1_2 */
|
||||||
BAP_QOS("24_2_2", LC3_CONFIG_FREQ_24KHZ, LC3_CONFIG_DURATION_10, false, 60, 13, 95, 40000, 2, "high-reliabilty"), /* 24_2_2 */
|
BAP_QOS("24_2_2", LC3_CONFIG_FREQ_24KHZ, LC3_CONFIG_DURATION_10, false, 60, 13, 95, 40000, 2, "high-reliability"), /* 24_2_2 */
|
||||||
BAP_QOS("32_1_2", LC3_CONFIG_FREQ_32KHZ, LC3_CONFIG_DURATION_7_5, false, 60, 13, 75, 40000, 13, "high-reliabilty"), /* 32_1_2 */
|
BAP_QOS("32_1_2", LC3_CONFIG_FREQ_32KHZ, LC3_CONFIG_DURATION_7_5, false, 60, 13, 75, 40000, 13, "high-reliability"), /* 32_1_2 */
|
||||||
BAP_QOS("32_2_2", LC3_CONFIG_FREQ_32KHZ, LC3_CONFIG_DURATION_10, false, 80, 13, 95, 40000, 3, "high-reliabilty"), /* 32_2_2 */
|
BAP_QOS("32_2_2", LC3_CONFIG_FREQ_32KHZ, LC3_CONFIG_DURATION_10, false, 80, 13, 95, 40000, 3, "high-reliability"), /* 32_2_2 */
|
||||||
BAP_QOS("441_1_2", LC3_CONFIG_FREQ_44KHZ, LC3_CONFIG_DURATION_7_5, true, 97, 13, 80, 40000, 54, "high-reliabilty"), /* 441_1_2 */
|
BAP_QOS("441_1_2", LC3_CONFIG_FREQ_44KHZ, LC3_CONFIG_DURATION_7_5, true, 97, 13, 80, 40000, 54, "high-reliability"), /* 441_1_2 */
|
||||||
BAP_QOS("441_2_2", LC3_CONFIG_FREQ_44KHZ, LC3_CONFIG_DURATION_10, true, 130, 13, 85, 40000, 44, "high-reliabilty"), /* 441_2_2 */
|
BAP_QOS("441_2_2", LC3_CONFIG_FREQ_44KHZ, LC3_CONFIG_DURATION_10, true, 130, 13, 85, 40000, 44, "high-reliability"), /* 441_2_2 */
|
||||||
BAP_QOS("48_1_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 75, 13, 75, 40000, 55, "high-reliabilty"), /* 48_1_2 */
|
BAP_QOS("48_1_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 75, 13, 75, 40000, 55, "high-reliability"), /* 48_1_2 */
|
||||||
BAP_QOS("48_2_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 100, 13, 95, 40000, 45, "high-reliabilty"), /* 48_2_2 */
|
BAP_QOS("48_2_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 100, 13, 95, 40000, 45, "high-reliability"), /* 48_2_2 */
|
||||||
BAP_QOS("48_3_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 90, 13, 75, 40000, 56, "high-reliabilty"), /* 48_3_2 */
|
BAP_QOS("48_3_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 90, 13, 75, 40000, 56, "high-reliability"), /* 48_3_2 */
|
||||||
BAP_QOS("48_4_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 120, 13, 100, 40000, 46, "high-reliabilty"), /* 48_4_2 */
|
BAP_QOS("48_4_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 120, 13, 100, 40000, 46, "high-reliability"), /* 48_4_2 */
|
||||||
BAP_QOS("48_5_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 117, 13, 75, 40000, 57, "high-reliabilty"), /* 48_5_2 */
|
BAP_QOS("48_5_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 117, 13, 75, 40000, 57, "high-reliability"), /* 48_5_2 */
|
||||||
BAP_QOS("48_6_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 155, 13, 100, 40000, 47, "high-reliabilty"), /* 48_6_2 */
|
BAP_QOS("48_6_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 155, 13, 100, 40000, 47, "high-reliability"), /* 48_6_2 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct bap_qos bap_bcast_qos_configs[] = {
|
static const struct bap_qos bap_bcast_qos_configs[] = {
|
||||||
|
|
@ -167,22 +167,22 @@ static const struct bap_qos bap_bcast_qos_configs[] = {
|
||||||
BAP_QOS("48_6_1", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 155, 4, 20, 40000, 27, "low-latency"), /* 48_6_1 */
|
BAP_QOS("48_6_1", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 155, 4, 20, 40000, 27, "low-latency"), /* 48_6_1 */
|
||||||
|
|
||||||
/* BAP v1.0.1 Table 6.4; high-reliability */
|
/* BAP v1.0.1 Table 6.4; high-reliability */
|
||||||
BAP_QOS("8_1_2", LC3_CONFIG_FREQ_8KHZ, LC3_CONFIG_DURATION_7_5, false, 26, 4, 45, 40000, 10, "high-reliabilty"), /* 8_1_2 */
|
BAP_QOS("8_1_2", LC3_CONFIG_FREQ_8KHZ, LC3_CONFIG_DURATION_7_5, false, 26, 4, 45, 40000, 10, "high-reliability"), /* 8_1_2 */
|
||||||
BAP_QOS("8_2_2", LC3_CONFIG_FREQ_8KHZ, LC3_CONFIG_DURATION_10, false, 30, 4, 60, 40000, 0, "high-reliabilty"), /* 8_2_2 */
|
BAP_QOS("8_2_2", LC3_CONFIG_FREQ_8KHZ, LC3_CONFIG_DURATION_10, false, 30, 4, 60, 40000, 0, "high-reliability"), /* 8_2_2 */
|
||||||
BAP_QOS("16_1_2", LC3_CONFIG_FREQ_16KHZ, LC3_CONFIG_DURATION_7_5, false, 30, 4, 45, 40000, 11, "high-reliabilty"), /* 16_1_2 */
|
BAP_QOS("16_1_2", LC3_CONFIG_FREQ_16KHZ, LC3_CONFIG_DURATION_7_5, false, 30, 4, 45, 40000, 11, "high-reliability"), /* 16_1_2 */
|
||||||
BAP_QOS("16_2_2", LC3_CONFIG_FREQ_16KHZ, LC3_CONFIG_DURATION_10, false, 40, 4, 60, 40000, 1, "high-reliabilty"), /* 16_2_2 */
|
BAP_QOS("16_2_2", LC3_CONFIG_FREQ_16KHZ, LC3_CONFIG_DURATION_10, false, 40, 4, 60, 40000, 1, "high-reliability"), /* 16_2_2 */
|
||||||
BAP_QOS("24_1_2", LC3_CONFIG_FREQ_24KHZ, LC3_CONFIG_DURATION_7_5, false, 45, 4, 45, 40000, 12, "high-reliabilty"), /* 24_1_2 */
|
BAP_QOS("24_1_2", LC3_CONFIG_FREQ_24KHZ, LC3_CONFIG_DURATION_7_5, false, 45, 4, 45, 40000, 12, "high-reliability"), /* 24_1_2 */
|
||||||
BAP_QOS("24_2_2", LC3_CONFIG_FREQ_24KHZ, LC3_CONFIG_DURATION_10, false, 60, 4, 60, 40000, 2, "high-reliabilty"), /* 24_2_2 */
|
BAP_QOS("24_2_2", LC3_CONFIG_FREQ_24KHZ, LC3_CONFIG_DURATION_10, false, 60, 4, 60, 40000, 2, "high-reliability"), /* 24_2_2 */
|
||||||
BAP_QOS("32_1_2", LC3_CONFIG_FREQ_32KHZ, LC3_CONFIG_DURATION_7_5, false, 60, 4, 45, 40000, 13, "high-reliabilty"), /* 32_1_2 */
|
BAP_QOS("32_1_2", LC3_CONFIG_FREQ_32KHZ, LC3_CONFIG_DURATION_7_5, false, 60, 4, 45, 40000, 13, "high-reliability"), /* 32_1_2 */
|
||||||
BAP_QOS("32_2_2", LC3_CONFIG_FREQ_32KHZ, LC3_CONFIG_DURATION_10, false, 80, 4, 60, 40000, 3, "high-reliabilty"), /* 32_2_2 */
|
BAP_QOS("32_2_2", LC3_CONFIG_FREQ_32KHZ, LC3_CONFIG_DURATION_10, false, 80, 4, 60, 40000, 3, "high-reliability"), /* 32_2_2 */
|
||||||
BAP_QOS("441_1_2", LC3_CONFIG_FREQ_44KHZ, LC3_CONFIG_DURATION_7_5, true, 97, 4, 54, 40000, 14, "high-reliabilty"), /* 441_1_2 */
|
BAP_QOS("441_1_2", LC3_CONFIG_FREQ_44KHZ, LC3_CONFIG_DURATION_7_5, true, 97, 4, 54, 40000, 14, "high-reliability"), /* 441_1_2 */
|
||||||
BAP_QOS("441_2_2", LC3_CONFIG_FREQ_44KHZ, LC3_CONFIG_DURATION_10, true, 130, 4, 60, 40000, 4, "high-reliabilty"), /* 441_2_2 */
|
BAP_QOS("441_2_2", LC3_CONFIG_FREQ_44KHZ, LC3_CONFIG_DURATION_10, true, 130, 4, 60, 40000, 4, "high-reliability"), /* 441_2_2 */
|
||||||
BAP_QOS("48_1_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 75, 4, 50, 40000, 15, "high-reliabilty"), /* 48_1_2 */
|
BAP_QOS("48_1_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 75, 4, 50, 40000, 15, "high-reliability"), /* 48_1_2 */
|
||||||
BAP_QOS("48_2_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 100, 4, 65, 40000, 5, "high-reliabilty"), /* 48_2_2 */
|
BAP_QOS("48_2_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 100, 4, 65, 40000, 5, "high-reliability"), /* 48_2_2 */
|
||||||
BAP_QOS("48_3_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 90, 4, 50, 40000, 16, "high-reliabilty"), /* 48_3_2 */
|
BAP_QOS("48_3_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 90, 4, 50, 40000, 16, "high-reliability"), /* 48_3_2 */
|
||||||
BAP_QOS("48_4_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 120, 4, 65, 40000, 6, "high-reliabilty"), /* 48_4_2 */
|
BAP_QOS("48_4_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 120, 4, 65, 40000, 6, "high-reliability"), /* 48_4_2 */
|
||||||
BAP_QOS("48_5_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 117, 4, 50, 40000, 17, "high-reliabilty"), /* 48_5_2 */
|
BAP_QOS("48_5_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_7_5, false, 117, 4, 50, 40000, 17, "high-reliability"), /* 48_5_2 */
|
||||||
BAP_QOS("48_6_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 155, 4, 65, 40000, 7, "high-reliabilty"), /* 48_6_2 */
|
BAP_QOS("48_6_2", LC3_CONFIG_FREQ_48KHZ, LC3_CONFIG_DURATION_10, false, 155, 4, 65, 40000, 7, "high-reliability"), /* 48_6_2 */
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int get_rate_mask(uint8_t rate) {
|
static unsigned int get_rate_mask(uint8_t rate) {
|
||||||
|
|
|
||||||
|
|
@ -587,18 +587,35 @@ static enum spa_bt_profile get_codec_profile(const struct media_codec *codec,
|
||||||
{
|
{
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case SPA_BT_MEDIA_SOURCE:
|
case SPA_BT_MEDIA_SOURCE:
|
||||||
return codec->kind == MEDIA_CODEC_BAP ? SPA_BT_PROFILE_BAP_SOURCE : SPA_BT_PROFILE_A2DP_SOURCE;
|
if (codec->kind == MEDIA_CODEC_A2DP)
|
||||||
|
return SPA_BT_PROFILE_A2DP_SOURCE;
|
||||||
|
else if (codec->kind == MEDIA_CODEC_BAP)
|
||||||
|
return SPA_BT_PROFILE_BAP_SOURCE;
|
||||||
|
else if (codec->kind == MEDIA_CODEC_HFP)
|
||||||
|
return SPA_BT_PROFILE_HEADSET_AUDIO;
|
||||||
|
else
|
||||||
|
return SPA_BT_PROFILE_NULL;
|
||||||
case SPA_BT_MEDIA_SINK:
|
case SPA_BT_MEDIA_SINK:
|
||||||
if (codec->kind == MEDIA_CODEC_ASHA)
|
if (codec->kind == MEDIA_CODEC_A2DP)
|
||||||
|
return SPA_BT_PROFILE_A2DP_SINK;
|
||||||
|
else if (codec->kind == MEDIA_CODEC_ASHA)
|
||||||
return SPA_BT_PROFILE_ASHA_SINK;
|
return SPA_BT_PROFILE_ASHA_SINK;
|
||||||
else if (codec->kind == MEDIA_CODEC_BAP)
|
else if (codec->kind == MEDIA_CODEC_BAP)
|
||||||
return SPA_BT_PROFILE_BAP_SINK;
|
return SPA_BT_PROFILE_BAP_SINK;
|
||||||
|
else if (codec->kind == MEDIA_CODEC_HFP)
|
||||||
|
return SPA_BT_PROFILE_HEADSET_AUDIO;
|
||||||
else
|
else
|
||||||
return SPA_BT_PROFILE_A2DP_SINK;
|
return SPA_BT_PROFILE_NULL;
|
||||||
case SPA_BT_MEDIA_SOURCE_BROADCAST:
|
case SPA_BT_MEDIA_SOURCE_BROADCAST:
|
||||||
return SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
|
if (codec->kind == MEDIA_CODEC_BAP)
|
||||||
|
return SPA_BT_PROFILE_BAP_BROADCAST_SOURCE;
|
||||||
|
else
|
||||||
|
return SPA_BT_PROFILE_NULL;
|
||||||
case SPA_BT_MEDIA_SINK_BROADCAST:
|
case SPA_BT_MEDIA_SINK_BROADCAST:
|
||||||
return SPA_BT_PROFILE_BAP_BROADCAST_SINK;
|
if (codec->kind == MEDIA_CODEC_BAP)
|
||||||
|
return SPA_BT_PROFILE_BAP_BROADCAST_SINK;
|
||||||
|
else
|
||||||
|
return SPA_BT_PROFILE_NULL;
|
||||||
default:
|
default:
|
||||||
spa_assert_not_reached();
|
spa_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
@ -2777,16 +2794,18 @@ bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const stru
|
||||||
bool is_bap = codec->kind == MEDIA_CODEC_BAP;
|
bool is_bap = codec->kind == MEDIA_CODEC_BAP;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
codec_target_profile = get_codec_target_profile(monitor, codec);
|
|
||||||
if (!codec_target_profile)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (codec->kind == MEDIA_CODEC_HFP) {
|
if (codec->kind == MEDIA_CODEC_HFP) {
|
||||||
if (!(profile & SPA_BT_PROFILE_HEADSET_AUDIO))
|
if (!(profile & SPA_BT_PROFILE_HEADSET_AUDIO))
|
||||||
return false;
|
return false;
|
||||||
|
if (!is_media_codec_enabled(monitor, codec))
|
||||||
|
return false;
|
||||||
return spa_bt_backend_supports_codec(monitor->backend, device, codec->codec_id) == 1;
|
return spa_bt_backend_supports_codec(monitor->backend, device, codec->codec_id) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
codec_target_profile = get_codec_target_profile(monitor, codec);
|
||||||
|
if (!codec_target_profile)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!device->adapter->a2dp_application_registered && is_a2dp) {
|
if (!device->adapter->a2dp_application_registered && is_a2dp) {
|
||||||
/* Codec switching not supported: only plain SBC allowed */
|
/* Codec switching not supported: only plain SBC allowed */
|
||||||
return (codec->codec_id == A2DP_CODEC_SBC && spa_streq(codec->name, "sbc") &&
|
return (codec->codec_id == A2DP_CODEC_SBC && spa_streq(codec->name, "sbc") &&
|
||||||
|
|
@ -7078,7 +7097,7 @@ static void parse_broadcast_source_config(struct spa_bt_monitor *monitor, const
|
||||||
memcpy(big_entry->broadcast_code, bcode, strlen(bcode));
|
memcpy(big_entry->broadcast_code, bcode, strlen(bcode));
|
||||||
spa_log_debug(monitor->log, "big_entry->broadcast_code %s", big_entry->broadcast_code);
|
spa_log_debug(monitor->log, "big_entry->broadcast_code %s", big_entry->broadcast_code);
|
||||||
} else if (spa_streq(key, "adapter")) {
|
} else if (spa_streq(key, "adapter")) {
|
||||||
if (spa_json_get_string(&it[1], big_entry->adapter, sizeof(big_entry->adapter)) <= 0)
|
if (spa_json_get_string(&it[0], big_entry->adapter, sizeof(big_entry->adapter)) <= 0)
|
||||||
goto parse_failed;
|
goto parse_failed;
|
||||||
spa_log_debug(monitor->log, "big_entry->adapter %s", big_entry->adapter);
|
spa_log_debug(monitor->log, "big_entry->adapter %s", big_entry->adapter);
|
||||||
} else if (spa_streq(key, "encryption")) {
|
} else if (spa_streq(key, "encryption")) {
|
||||||
|
|
|
||||||
|
|
@ -1784,7 +1784,7 @@ static uint32_t get_samples(struct impl *this, int64_t *duration_ns)
|
||||||
static void update_target_latency(struct impl *this)
|
static void update_target_latency(struct impl *this)
|
||||||
{
|
{
|
||||||
struct port *port = &this->port;
|
struct port *port = &this->port;
|
||||||
int32_t target;
|
int32_t target = 0;
|
||||||
int samples;
|
int samples;
|
||||||
|
|
||||||
if (this->transport == NULL || !port->have_format)
|
if (this->transport == NULL || !port->have_format)
|
||||||
|
|
@ -1803,7 +1803,7 @@ static void update_target_latency(struct impl *this)
|
||||||
*/
|
*/
|
||||||
if (this->decode_buffer_target)
|
if (this->decode_buffer_target)
|
||||||
target = this->decode_buffer_target;
|
target = this->decode_buffer_target;
|
||||||
else
|
else if (this->transport->iso_io)
|
||||||
target = spa_bt_iso_io_get_source_target_latency(this->transport->iso_io);
|
target = spa_bt_iso_io_get_source_target_latency(this->transport->iso_io);
|
||||||
|
|
||||||
spa_bt_decode_buffer_set_target_latency(&port->buffer, target);
|
spa_bt_decode_buffer_set_target_latency(&port->buffer, target);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue