[pulseaudio-discuss] [PATCH] bluetooth-device: Add safe guard against BT streaming irregularities.

Jyri Sarha LEPBTETFMVBZ at spammotel.com
Fri May 8 03:25:21 PDT 2009


From: Jyri Sarha <jyri.sarha at nokia.com>

Some bad quality BT-headsets block bluez socket sometimes for hundreds
of milliseconds, especially when changing mode. When the module tries
catch up the lost time it may SBC encode up to half a second of audio
without yielding. On slow machine this may cause maximum RT time slice
to be exceeded. Cleaned out the minor fix that slipped into first version
of the patch.
---
 src/modules/bluetooth/module-bluetooth-device.c |   22 ++++++++++++++++++----
 1 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index ecb5e83..1b42f4a 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -174,6 +174,8 @@ struct userdata {
 #define FIXED_LATENCY_PLAYBACK_HSP (125*PA_USEC_PER_MSEC)
 #define FIXED_LATENCY_RECORD_HSP (25*PA_USEC_PER_MSEC)
 
+#define MAX_PLAYBACK_CATCH_UP_USEC (100*PA_USEC_PER_MSEC)
+
 #ifdef NOKIA
 #define USE_SCO_OVER_PCM(u) (u->profile == PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source))
 #endif
@@ -1296,15 +1298,27 @@ static void thread_func(void *userdata) {
 
                 if ((!u->source || !PA_SOURCE_IS_LINKED(u->source->thread_info.state)) && do_write <= 0 && writable) {
                     pa_usec_t time_passed;
-                    uint64_t should_have_written;
+                    pa_usec_t audio_sent;
 
                     /* Hmm, there is no input stream we could synchronize
                      * to. So let's do things by time */
 
                     time_passed = pa_rtclock_usec() - u->started_at;
-                    should_have_written = pa_usec_to_bytes(time_passed, &u->sample_spec);
-
-                    do_write = u->write_index <= should_have_written;
+                    audio_sent = pa_bytes_to_usec(u->write_index, &u->sample_spec);
+
+                    if (audio_sent <= time_passed) {
+                        pa_usec_t audio_to_send = time_passed - audio_sent;
+                        if (u->write_index > 0 && audio_to_send > MAX_PLAYBACK_CATCH_UP_USEC) {
+                            pa_usec_t skip_usec = audio_to_send - MAX_PLAYBACK_CATCH_UP_USEC;
+                            uint64_t skip_bytes = pa_usec_to_bytes(skip_usec, &u->sample_spec);
+                            pa_memchunk tmp;
+                            pa_log_warn("Skipping %lld us (= %lld bytes) in audio stream", skip_usec, skip_bytes);
+                            pa_sink_render_full(u->sink, skip_bytes, &tmp);
+                            pa_memblock_unref(tmp.memblock);
+                            u->write_index += skip_bytes;
+                        }
+                        do_write = 1;
+                    }
                 }
 
                 if (writable && do_write > 0) {
-- 
1.5.6.3




More information about the pulseaudio-discuss mailing list