mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-01 07:15:39 -04:00
Merge branch 'bt-latency-quality-codecs' into 'master'
bluez: Add A2DP auto quality and latency profiles See merge request pipewire/pipewire!2752
This commit is contained in:
commit
c9503704ab
1 changed files with 184 additions and 8 deletions
|
|
@ -59,6 +59,8 @@ enum device_profile {
|
||||||
DEVICE_PROFILE_OFF = 0,
|
DEVICE_PROFILE_OFF = 0,
|
||||||
DEVICE_PROFILE_AG,
|
DEVICE_PROFILE_AG,
|
||||||
DEVICE_PROFILE_A2DP,
|
DEVICE_PROFILE_A2DP,
|
||||||
|
DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY,
|
||||||
|
DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY,
|
||||||
DEVICE_PROFILE_HSP_HFP,
|
DEVICE_PROFILE_HSP_HFP,
|
||||||
DEVICE_PROFILE_BAP,
|
DEVICE_PROFILE_BAP,
|
||||||
DEVICE_PROFILE_BAP_SINK,
|
DEVICE_PROFILE_BAP_SINK,
|
||||||
|
|
@ -67,6 +69,12 @@ enum device_profile {
|
||||||
DEVICE_PROFILE_LAST,
|
DEVICE_PROFILE_LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum codec_order {
|
||||||
|
CODEC_ORDER_NONE = 0,
|
||||||
|
CODEC_ORDER_QUALITY,
|
||||||
|
CODEC_ORDER_LATENCY,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ROUTE_INPUT = 0,
|
ROUTE_INPUT = 0,
|
||||||
ROUTE_OUTPUT,
|
ROUTE_OUTPUT,
|
||||||
|
|
@ -204,9 +212,113 @@ static bool profile_is_bap(enum device_profile profile)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_media_codecs(struct impl *this, enum spa_bluetooth_audio_codec id, const struct media_codec **codecs, size_t size)
|
static bool profile_is_a2dp(enum device_profile profile)
|
||||||
|
{
|
||||||
|
switch (profile) {
|
||||||
|
case DEVICE_PROFILE_A2DP:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t get_media_codec_quality_priority (const struct media_codec *mc)
|
||||||
|
{
|
||||||
|
/* From lowest quality to highest quality */
|
||||||
|
static const enum spa_bluetooth_audio_codec quality_priorities[] = {
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_START,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_G,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_MPEG,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_SBC,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_APTX,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_AAC_ELD,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_AAC,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_LC3PLUS_HR,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_APTX_HD,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_LDAC
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; SPA_N_ELEMENTS(quality_priorities); ++i) {
|
||||||
|
if (quality_priorities[i] == mc->id)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t get_media_codec_latency_priority (const struct media_codec *mc)
|
||||||
|
{
|
||||||
|
/* From highest latency to lowest latency */
|
||||||
|
static const enum spa_bluetooth_audio_codec latency_priorities[] = {
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_START,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_71,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_51,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_PRO,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_G,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_OPUS_05_DUPLEX,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_MPEG,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_AAC,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_AAC_ELD,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_APTX_HD,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_LDAC,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_LC3PLUS_HR,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_SBC,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_APTX,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX,
|
||||||
|
SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL,
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; SPA_N_ELEMENTS(latency_priorities); ++i) {
|
||||||
|
if (latency_priorities[i] == mc->id)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int media_codec_quality_cmp(const void *a, const void *b) {
|
||||||
|
const struct media_codec *ca = *(const struct media_codec **)a;
|
||||||
|
const struct media_codec *cb = *(const struct media_codec **)b;
|
||||||
|
size_t ca_prio = get_media_codec_quality_priority (ca);
|
||||||
|
size_t cb_prio = get_media_codec_quality_priority (cb);
|
||||||
|
if (ca_prio > cb_prio) return -1;
|
||||||
|
if (ca_prio < cb_prio) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int media_codec_latency_cmp(const void *a, const void *b) {
|
||||||
|
const struct media_codec *ca = *(const struct media_codec **)a;
|
||||||
|
const struct media_codec *cb = *(const struct media_codec **)b;
|
||||||
|
size_t ca_prio = get_media_codec_latency_priority (ca);
|
||||||
|
size_t cb_prio = get_media_codec_latency_priority (cb);
|
||||||
|
if (ca_prio > cb_prio) return -1;
|
||||||
|
if (ca_prio < cb_prio) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_media_codecs(struct impl *this, enum codec_order order, enum spa_bluetooth_audio_codec id, const struct media_codec **codecs, size_t size)
|
||||||
{
|
{
|
||||||
const struct media_codec * const *c;
|
const struct media_codec * const *c;
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
spa_assert(size > 0);
|
spa_assert(size > 0);
|
||||||
spa_assert(this->supported_codecs);
|
spa_assert(this->supported_codecs);
|
||||||
|
|
@ -216,12 +328,24 @@ static void get_media_codecs(struct impl *this, enum spa_bluetooth_audio_codec i
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((*c)->id == id || id == 0) {
|
if ((*c)->id == id || id == 0) {
|
||||||
*codecs++ = *c;
|
codecs[n++] = *c;
|
||||||
--size;
|
--size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*codecs = NULL;
|
codecs[n] = NULL;
|
||||||
|
|
||||||
|
switch (order) {
|
||||||
|
case CODEC_ORDER_QUALITY:
|
||||||
|
qsort(codecs, n, sizeof(struct media_codec *), media_codec_quality_cmp);
|
||||||
|
break;
|
||||||
|
case CODEC_ORDER_LATENCY:
|
||||||
|
qsort(codecs, n, sizeof(struct media_codec *), media_codec_latency_cmp);
|
||||||
|
break;
|
||||||
|
case CODEC_ORDER_NONE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct media_codec *get_supported_media_codec(struct impl *this, enum spa_bluetooth_audio_codec id,
|
static const struct media_codec *get_supported_media_codec(struct impl *this, enum spa_bluetooth_audio_codec id,
|
||||||
|
|
@ -380,6 +504,8 @@ static bool node_update_volume_from_transport(struct node *node, bool reset)
|
||||||
|
|
||||||
/* PW is the controller for remote device. */
|
/* PW is the controller for remote device. */
|
||||||
if (impl->profile != DEVICE_PROFILE_A2DP
|
if (impl->profile != DEVICE_PROFILE_A2DP
|
||||||
|
&& impl->profile != DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY
|
||||||
|
&& impl->profile != DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY
|
||||||
&& impl->profile != DEVICE_PROFILE_BAP
|
&& impl->profile != DEVICE_PROFILE_BAP
|
||||||
&& impl->profile != DEVICE_PROFILE_BAP_SINK
|
&& impl->profile != DEVICE_PROFILE_BAP_SINK
|
||||||
&& impl->profile != DEVICE_PROFILE_BAP_SOURCE
|
&& impl->profile != DEVICE_PROFILE_BAP_SOURCE
|
||||||
|
|
@ -1262,6 +1388,8 @@ static int emit_nodes(struct impl *this)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEVICE_PROFILE_A2DP:
|
case DEVICE_PROFILE_A2DP:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE) {
|
if (this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE) {
|
||||||
t = find_transport(this, SPA_BT_PROFILE_A2DP_SOURCE);
|
t = find_transport(this, SPA_BT_PROFILE_A2DP_SOURCE);
|
||||||
if (t) {
|
if (t) {
|
||||||
|
|
@ -1464,13 +1592,13 @@ static int set_profile(struct impl *this, uint32_t profile, enum spa_bluetooth_a
|
||||||
* XXX: source-only case, as it will only switch the sink, and we only
|
* XXX: source-only case, as it will only switch the sink, and we only
|
||||||
* XXX: list the sink codecs here. TODO: fix this
|
* XXX: list the sink codecs here. TODO: fix this
|
||||||
*/
|
*/
|
||||||
if ((profile == DEVICE_PROFILE_A2DP || (profile_is_bap(profile) && is_bap_client(this)))
|
if ((profile_is_a2dp (profile) || (profile_is_bap(profile) && is_bap_client(this)))
|
||||||
&& !(this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE)) {
|
&& !(this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_SOURCE)) {
|
||||||
int ret;
|
int ret;
|
||||||
const struct media_codec *codecs[64];
|
const struct media_codec *codecs[64];
|
||||||
uint32_t profiles;
|
uint32_t profiles;
|
||||||
|
|
||||||
get_media_codecs(this, codec, codecs, SPA_N_ELEMENTS(codecs));
|
get_media_codecs(this, CODEC_ORDER_NONE, codec, codecs, SPA_N_ELEMENTS(codecs));
|
||||||
|
|
||||||
this->switching_codec = true;
|
this->switching_codec = true;
|
||||||
|
|
||||||
|
|
@ -1487,6 +1615,14 @@ static int set_profile(struct impl *this, uint32_t profile, enum spa_bluetooth_a
|
||||||
case DEVICE_PROFILE_A2DP:
|
case DEVICE_PROFILE_A2DP:
|
||||||
profiles = this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_DUPLEX;
|
profiles = this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_DUPLEX;
|
||||||
break;
|
break;
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
get_media_codecs(this, CODEC_ORDER_QUALITY, 0, codecs, SPA_N_ELEMENTS(codecs));
|
||||||
|
profiles = this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_DUPLEX;
|
||||||
|
break;
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
|
get_media_codecs(this, CODEC_ORDER_LATENCY, 0, codecs, SPA_N_ELEMENTS(codecs));
|
||||||
|
profiles = this->bt_dev->connected_profiles & SPA_BT_PROFILE_A2DP_DUPLEX;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
profiles = 0;
|
profiles = 0;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1646,6 +1782,8 @@ static void profiles_changed(void *userdata, uint32_t connected_change)
|
||||||
nodes_changed);
|
nodes_changed);
|
||||||
break;
|
break;
|
||||||
case DEVICE_PROFILE_A2DP:
|
case DEVICE_PROFILE_A2DP:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
nodes_changed = (connected_change & SPA_BT_PROFILE_A2DP_DUPLEX);
|
nodes_changed = (connected_change & SPA_BT_PROFILE_A2DP_DUPLEX);
|
||||||
spa_log_debug(this->log, "profiles changed: A2DP nodes changed: %d",
|
spa_log_debug(this->log, "profiles changed: A2DP nodes changed: %d",
|
||||||
nodes_changed);
|
nodes_changed);
|
||||||
|
|
@ -1801,6 +1939,8 @@ static uint32_t profile_direction_mask(struct impl *this, uint32_t index, enum s
|
||||||
|
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case DEVICE_PROFILE_A2DP:
|
case DEVICE_PROFILE_A2DP:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
if (device->connected_profiles & SPA_BT_PROFILE_A2DP_SINK)
|
if (device->connected_profiles & SPA_BT_PROFILE_A2DP_SINK)
|
||||||
have_output = true;
|
have_output = true;
|
||||||
|
|
||||||
|
|
@ -1850,6 +1990,8 @@ static uint32_t get_profile_from_index(struct impl *this, uint32_t index, uint32
|
||||||
switch (profile) {
|
switch (profile) {
|
||||||
case DEVICE_PROFILE_OFF:
|
case DEVICE_PROFILE_OFF:
|
||||||
case DEVICE_PROFILE_AG:
|
case DEVICE_PROFILE_AG:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
*codec = 0;
|
*codec = 0;
|
||||||
*next = (profile + 1) << 16;
|
*next = (profile + 1) << 16;
|
||||||
return profile;
|
return profile;
|
||||||
|
|
@ -1884,6 +2026,8 @@ static uint32_t get_index_from_profile(struct impl *this, uint32_t profile, enum
|
||||||
switch (profile) {
|
switch (profile) {
|
||||||
case DEVICE_PROFILE_OFF:
|
case DEVICE_PROFILE_OFF:
|
||||||
case DEVICE_PROFILE_AG:
|
case DEVICE_PROFILE_AG:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
return (profile << 16);
|
return (profile << 16);
|
||||||
|
|
||||||
case DEVICE_PROFILE_ASHA:
|
case DEVICE_PROFILE_ASHA:
|
||||||
|
|
@ -2123,6 +2267,36 @@ static struct spa_pod *build_profile(struct impl *this, struct spa_pod_builder *
|
||||||
n_source++;
|
n_source++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
|
{
|
||||||
|
uint32_t profile;
|
||||||
|
|
||||||
|
/* make this device profile visible only if there is an A2DP sink */
|
||||||
|
profile = device->connected_profiles & (SPA_BT_PROFILE_A2DP_SINK | SPA_BT_PROFILE_A2DP_SOURCE);
|
||||||
|
if (!(profile & SPA_BT_PROFILE_A2DP_SINK))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
switch (profile_index) {
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
name = "a2dp-auto-prefer-quality";
|
||||||
|
desc = _("Auto: Prefer Quality (A2DP)");
|
||||||
|
break;
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
|
name = "a2dp-auto-prefer-latency";
|
||||||
|
desc = _("Auto: Prefer Latency (A2DP)");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
priority = 0;
|
||||||
|
|
||||||
|
n_sink++;
|
||||||
|
if (this->autoswitch_routes && (device->connected_profiles & SPA_BT_PROFILE_HEADSET_HEAD_UNIT))
|
||||||
|
n_source++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DEVICE_PROFILE_BAP_SINK:
|
case DEVICE_PROFILE_BAP_SINK:
|
||||||
case DEVICE_PROFILE_BAP_SOURCE:
|
case DEVICE_PROFILE_BAP_SOURCE:
|
||||||
/* These are client-only */
|
/* These are client-only */
|
||||||
|
|
@ -2324,6 +2498,8 @@ static bool profile_has_route(uint32_t profile, uint32_t route)
|
||||||
case DEVICE_PROFILE_AG:
|
case DEVICE_PROFILE_AG:
|
||||||
break;
|
break;
|
||||||
case DEVICE_PROFILE_A2DP:
|
case DEVICE_PROFILE_A2DP:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_QUALITY:
|
||||||
|
case DEVICE_PROFILE_A2DP_AUTO_PREFER_LATENCY:
|
||||||
switch (route) {
|
switch (route) {
|
||||||
case ROUTE_INPUT:
|
case ROUTE_INPUT:
|
||||||
case ROUTE_OUTPUT:
|
case ROUTE_OUTPUT:
|
||||||
|
|
@ -2623,7 +2799,7 @@ static struct spa_pod *build_route(struct impl *this, struct spa_pod_builder *b,
|
||||||
spa_pod_builder_array(b, sizeof(uint32_t), SPA_TYPE_Id,
|
spa_pod_builder_array(b, sizeof(uint32_t), SPA_TYPE_Id,
|
||||||
node->n_channels, node->channels);
|
node->n_channels, node->channels);
|
||||||
|
|
||||||
if ((this->profile == DEVICE_PROFILE_A2DP || profile_is_bap(this->profile)) &&
|
if ((profile_is_a2dp (this->profile) || profile_is_bap(this->profile)) &&
|
||||||
(dev & SINK_ID_FLAG)) {
|
(dev & SINK_ID_FLAG)) {
|
||||||
spa_pod_builder_prop(b, SPA_PROP_latencyOffsetNsec, 0);
|
spa_pod_builder_prop(b, SPA_PROP_latencyOffsetNsec, 0);
|
||||||
spa_pod_builder_long(b, node->latency_offset);
|
spa_pod_builder_long(b, node->latency_offset);
|
||||||
|
|
@ -2659,7 +2835,7 @@ next:
|
||||||
|
|
||||||
c = this->supported_codecs[*j];
|
c = this->supported_codecs[*j];
|
||||||
|
|
||||||
if (!(this->profile == DEVICE_PROFILE_A2DP && c->kind == MEDIA_CODEC_A2DP) &&
|
if (!(profile_is_a2dp (this->profile) && c->kind == MEDIA_CODEC_A2DP) &&
|
||||||
!(profile_is_bap(this->profile) && c->kind == MEDIA_CODEC_BAP) &&
|
!(profile_is_bap(this->profile) && c->kind == MEDIA_CODEC_BAP) &&
|
||||||
!(this->profile == DEVICE_PROFILE_HSP_HFP && c->kind == MEDIA_CODEC_HFP) &&
|
!(this->profile == DEVICE_PROFILE_HSP_HFP && c->kind == MEDIA_CODEC_HFP) &&
|
||||||
!(this->profile == DEVICE_PROFILE_ASHA && c->kind == MEDIA_CODEC_ASHA))
|
!(this->profile == DEVICE_PROFILE_ASHA && c->kind == MEDIA_CODEC_ASHA))
|
||||||
|
|
@ -3240,7 +3416,7 @@ static int impl_set_param(void *object,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->profile == DEVICE_PROFILE_A2DP || profile_is_bap(this->profile) ||
|
if (profile_is_a2dp (this->profile) || profile_is_bap(this->profile) ||
|
||||||
this->profile == DEVICE_PROFILE_ASHA || this->profile == DEVICE_PROFILE_HSP_HFP) {
|
this->profile == DEVICE_PROFILE_ASHA || this->profile == DEVICE_PROFILE_HSP_HFP) {
|
||||||
size_t j;
|
size_t j;
|
||||||
for (j = 0; j < this->supported_codec_count; ++j) {
|
for (j = 0; j < this->supported_codec_count; ++j) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue