[pulseaudio-discuss] [PATCH] bluetooth-device: Add safe guard against BT streaming irregularities.
Jyri Sarha
jyri.sarha at nokia.com
Thu May 7 09:54:58 PDT 2009
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.
---
src/modules/bluetooth/module-bluetooth-device.c | 27 ++++++++++++++++++----
1 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index ecb5e83..2a70496 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) {
@@ -1822,8 +1836,11 @@ static int start_thread(struct userdata *u) {
#ifdef NOKIA
if (USE_SCO_OVER_PCM(u)) {
- if (start_stream_fd(u) < 0)
+ if (start_stream_fd(u) < 0) {
+ u->sink = NULL;
+ u->source = NULL;
return -1;
+ }
pa_sink_ref(u->sink);
pa_source_ref(u->source);
--
1.5.6.3
More information about the pulseaudio-discuss
mailing list