[RFCv3 20/20] bluetooth: Update sink/source sample rate on HFP play

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux