mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-03 09:01:50 -05:00
bluetooth: Fix HSP volume handling.
Previously the userdata for the volume callbacks was saved to pa_core.shared only once when loading module-bluetooth-device, and only when the SCO over PCM feature was used. That breaks volume handling in cases where the HSP profile is used without the SCO over PCM setup. Now the userdata is set always when a sink or source is created, and removed when a sink or source is removed.
This commit is contained in:
parent
ccbf7a3006
commit
35c93f711d
1 changed files with 69 additions and 32 deletions
|
|
@ -1959,6 +1959,8 @@ static pa_hook_result_t source_state_changed_cb(pa_core *c, pa_source *s, struct
|
|||
|
||||
/* Run from main thread */
|
||||
static int add_sink(struct userdata *u) {
|
||||
char *k;
|
||||
|
||||
if (USE_SCO_OVER_PCM(u)) {
|
||||
pa_proplist *p;
|
||||
|
||||
|
|
@ -2012,6 +2014,10 @@ static int add_sink(struct userdata *u) {
|
|||
if (u->profile == PROFILE_HSP) {
|
||||
u->sink->set_volume = sink_set_volume_cb;
|
||||
u->sink->n_volume_steps = 16;
|
||||
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink);
|
||||
pa_shared_set(u->core, k, u);
|
||||
pa_xfree(k);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -2019,6 +2025,8 @@ static int add_sink(struct userdata *u) {
|
|||
|
||||
/* Run from main thread */
|
||||
static int add_source(struct userdata *u) {
|
||||
char *k;
|
||||
|
||||
if (USE_SCO_OVER_PCM(u)) {
|
||||
u->source = u->hsp.sco_source;
|
||||
pa_proplist_sets(u->source->proplist, "bluetooth.protocol", "hsp");
|
||||
|
|
@ -2077,6 +2085,10 @@ static int add_source(struct userdata *u) {
|
|||
if (u->profile == PROFILE_HSP) {
|
||||
u->source->set_volume = source_set_volume_cb;
|
||||
u->source->n_volume_steps = 16;
|
||||
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->source);
|
||||
pa_shared_set(u->core, k, u);
|
||||
pa_xfree(k);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -2323,6 +2335,8 @@ static int init_profile(struct userdata *u) {
|
|||
|
||||
/* Run from main thread */
|
||||
static void stop_thread(struct userdata *u) {
|
||||
char *k;
|
||||
|
||||
pa_assert(u);
|
||||
|
||||
if (u->thread) {
|
||||
|
|
@ -2347,11 +2361,23 @@ static void stop_thread(struct userdata *u) {
|
|||
}
|
||||
|
||||
if (u->sink) {
|
||||
if (u->profile == PROFILE_HSP) {
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink);
|
||||
pa_shared_remove(u->core, k);
|
||||
pa_xfree(k);
|
||||
}
|
||||
|
||||
pa_sink_unref(u->sink);
|
||||
u->sink = NULL;
|
||||
}
|
||||
|
||||
if (u->source) {
|
||||
if (u->profile == PROFILE_HSP) {
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->source);
|
||||
pa_shared_remove(u->core, k);
|
||||
pa_xfree(k);
|
||||
}
|
||||
|
||||
pa_source_unref(u->source);
|
||||
u->source = NULL;
|
||||
}
|
||||
|
|
@ -2381,8 +2407,20 @@ static int start_thread(struct userdata *u) {
|
|||
|
||||
if (USE_SCO_OVER_PCM(u)) {
|
||||
if (sco_over_pcm_state_update(u) < 0) {
|
||||
char *k;
|
||||
|
||||
if (u->sink) {
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink);
|
||||
pa_shared_remove(u->core, k);
|
||||
pa_xfree(k);
|
||||
u->sink = NULL;
|
||||
}
|
||||
if (u->source) {
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->source);
|
||||
pa_shared_remove(u->core, k);
|
||||
pa_xfree(k);
|
||||
u->source = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -2419,6 +2457,22 @@ static int start_thread(struct userdata *u) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void save_sco_volume_callbacks(struct userdata *u) {
|
||||
pa_assert(u);
|
||||
pa_assert(USE_SCO_OVER_PCM(u));
|
||||
|
||||
u->hsp.sco_sink_set_volume = u->hsp.sco_sink->set_volume;
|
||||
u->hsp.sco_source_set_volume = u->hsp.sco_source->set_volume;
|
||||
}
|
||||
|
||||
static void restore_sco_volume_callbacks(struct userdata *u) {
|
||||
pa_assert(u);
|
||||
pa_assert(USE_SCO_OVER_PCM(u));
|
||||
|
||||
u->hsp.sco_sink->set_volume = u->hsp.sco_sink_set_volume;
|
||||
u->hsp.sco_source->set_volume = u->hsp.sco_source_set_volume;
|
||||
}
|
||||
|
||||
/* Run from main thread */
|
||||
static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
|
||||
struct userdata *u;
|
||||
|
|
@ -2472,9 +2526,15 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
|
|||
stop_thread(u);
|
||||
shutdown_bt(u);
|
||||
|
||||
if (USE_SCO_OVER_PCM(u))
|
||||
restore_sco_volume_callbacks(u);
|
||||
|
||||
u->profile = *d;
|
||||
u->sample_spec = u->requested_sample_spec;
|
||||
|
||||
if (USE_SCO_OVER_PCM(u))
|
||||
save_sco_volume_callbacks(u);
|
||||
|
||||
init_bt(u);
|
||||
|
||||
if (u->profile != PROFILE_OFF)
|
||||
|
|
@ -2639,6 +2699,9 @@ static int add_card(struct userdata *u, const pa_bluetooth_device *device) {
|
|||
d = PA_CARD_PROFILE_DATA(u->card->active_profile);
|
||||
u->profile = *d;
|
||||
|
||||
if (USE_SCO_OVER_PCM(u))
|
||||
save_sco_volume_callbacks(u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2702,7 +2765,7 @@ int pa__init(pa_module* m) {
|
|||
struct userdata *u;
|
||||
const char *address, *path;
|
||||
DBusError err;
|
||||
char *mike, *speaker, *transport, *k;
|
||||
char *mike, *speaker, *transport;
|
||||
const pa_bluetooth_device *device;
|
||||
|
||||
pa_assert(m);
|
||||
|
|
@ -2803,20 +2866,6 @@ int pa__init(pa_module* m) {
|
|||
/* Connect to the BT service */
|
||||
init_bt(u);
|
||||
|
||||
if (u->hsp.sco_sink) {
|
||||
u->hsp.sco_sink_set_volume = u->hsp.sco_sink->set_volume;
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->hsp.sco_sink);
|
||||
pa_shared_set(u->core, k, u);
|
||||
pa_xfree(k);
|
||||
}
|
||||
|
||||
if (u->hsp.sco_source) {
|
||||
u->hsp.sco_source_set_volume = u->hsp.sco_source->set_volume;
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->hsp.sco_source);
|
||||
pa_shared_set(u->core, k, u);
|
||||
pa_xfree(k);
|
||||
}
|
||||
|
||||
if (u->profile != PROFILE_OFF)
|
||||
if (init_profile(u) < 0)
|
||||
goto fail;
|
||||
|
|
@ -2849,7 +2898,6 @@ int pa__get_n_used(pa_module *m) {
|
|||
|
||||
void pa__done(pa_module *m) {
|
||||
struct userdata *u;
|
||||
char *k;
|
||||
|
||||
pa_assert(m);
|
||||
|
||||
|
|
@ -2864,6 +2912,9 @@ void pa__done(pa_module *m) {
|
|||
|
||||
stop_thread(u);
|
||||
|
||||
if (USE_SCO_OVER_PCM(u))
|
||||
restore_sco_volume_callbacks(u);
|
||||
|
||||
if (u->connection) {
|
||||
|
||||
if (u->path) {
|
||||
|
|
@ -2891,20 +2942,6 @@ void pa__done(pa_module *m) {
|
|||
|
||||
shutdown_bt(u);
|
||||
|
||||
if (u->hsp.sco_sink) {
|
||||
u->hsp.sco_sink->set_volume = u->hsp.sco_sink_set_volume;
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->hsp.sco_sink);
|
||||
pa_shared_remove(u->core, k);
|
||||
pa_xfree(k);
|
||||
}
|
||||
|
||||
if (u->hsp.sco_source) {
|
||||
u->hsp.sco_source->set_volume = u->hsp.sco_source_set_volume;
|
||||
k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->hsp.sco_source);
|
||||
pa_shared_remove(u->core, k);
|
||||
pa_xfree(k);
|
||||
}
|
||||
|
||||
if (u->a2dp.buffer)
|
||||
pa_xfree(u->a2dp.buffer);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue