From: Jo?o Paulo Rechi Vita <jprvita@xxxxxxxxxxxxx> For oFono-backed HFP the stream sample rate is only known whe the transport changes its state to playing, as a paramenter of NewConnection(). On this moment if the stream sample rate is different from the sink/source one, the sink-inputs/source-outputs are stashed, the sink and source are destroyed and re-created with the new rate, and the sink-inputs/source-outputs restored. --- src/modules/bluetooth/module-bluetooth-device.c | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index a94fa4e..f418cc9 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1585,6 +1585,40 @@ static pa_available_t get_port_availability(struct userdata *u, pa_direction_t d return result; } +static void stop_thread(struct userdata *u); +static int start_thread(struct userdata *u); + +/* Run from main thread */ +static void update_rate(struct userdata *u, uint32_t rate) { + pa_queue *sink_inputs = NULL, *source_outputs = NULL; + + pa_assert(u); + + if (u->sample_spec.rate == rate) + return; + + sink_inputs = pa_sink_move_all_start(u->sink, sink_inputs); + source_outputs = pa_source_move_all_start(u->source, source_outputs); + u->stream_fd = -1; + stop_thread(u); + + u->sample_spec.rate = rate; + init_profile(u); + start_thread(u); + + if (!u->sink && sink_inputs) + pa_sink_move_all_fail(sink_inputs); + + if (!u->source && source_outputs) + pa_source_move_all_fail(source_outputs); + + if (u->sink && sink_inputs) + pa_sink_move_all_finish(u->sink, sink_inputs, FALSE); + + if (u->source && source_outputs) + pa_source_move_all_finish(u->source, source_outputs, FALSE); +} + /* Run from main thread */ static void handle_transport_state_change(struct userdata *u, struct pa_bluetooth_transport *transport) { bool acquire = false; @@ -1619,6 +1653,10 @@ static void handle_transport_state_change(struct userdata *u, struct pa_bluetoot if (acquire) if (bt_transport_acquire(u, true) >= 0) { + + if ((pa_bluetooth_discovery_get_bluez_version(u->discovery) == BLUEZ_VERSION_5) && profile == PROFILE_HFGW) + update_rate(u, (transport->codec == HFP_AUDIO_CODEC_CVSD) ? 8000 : 16000); + if (u->source) { pa_log_debug("Resuming source %s, because the bluetooth audio state changed to 'playing'.", u->source->name); pa_source_suspend(u->source, false, PA_SUSPEND_IDLE|PA_SUSPEND_USER); -- 1.7.11.7