[pulseaudio-discuss] [RFC v0] bluetooth: Send time-based output audio
Mikel Astiz
mikel.astiz.oss at gmail.com
Fri Jun 28 07:50:48 PDT 2013
From: Mikel Astiz <mikel.astiz at bmw-carit.de>
The previous implementation to send 2 packets first and then try to
account the received packets vs sent packets seems to generate some
issues in several devices. The alternative is to always do it
time-based.
---
This is WIP and thus not intended to be merged.
I'm submitting this to see if it improves some issues recently reported with several devices, leading to no audio when using HSP/HFP. hcidump showed that no packets were being sent by neither of the ends.
src/modules/bluetooth/module-bluetooth-device.c | 25 ++++++-------------------
1 file changed, 6 insertions(+), 19 deletions(-)
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index ea3db48..bdaa3ad 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -989,8 +989,6 @@ static void a2dp_reduce_bitpool(struct userdata *u) {
static void thread_func(void *userdata) {
struct userdata *u = userdata;
- unsigned do_write = 0;
- unsigned pending_read_bytes = 0;
bool writable = false;
pa_assert(u);
@@ -1011,17 +1009,11 @@ static void thread_func(void *userdata) {
struct pollfd *pollfd;
int ret;
bool disable_timer = true;
+ unsigned do_write = 0;
pollfd = u->rtpoll_item ? pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL) : NULL;
if (u->source && PA_SOURCE_IS_LINKED(u->source->thread_info.state)) {
-
- /* We should send two blocks to the device before we expect
- * a response. */
-
- if (u->write_index == 0 && u->read_index <= 0)
- do_write = 2;
-
if (pollfd && (pollfd->revents & POLLIN)) {
int n_read;
@@ -1032,11 +1024,6 @@ static void thread_func(void *userdata) {
if (n_read < 0)
goto io_fail;
-
- /* We just read something, so we are supposed to write something, too */
- pending_read_bytes += n_read;
- do_write += pending_read_bytes / u->write_block_size;
- pending_read_bytes = pending_read_bytes % u->write_block_size;
}
}
@@ -1049,7 +1036,8 @@ static void thread_func(void *userdata) {
if (pollfd->revents & POLLOUT)
writable = true;
- if ((!u->source || !PA_SOURCE_IS_LINKED(u->source->thread_info.state)) && do_write <= 0 && writable) {
+ /* Force time based scheduling for outgoing packets */
+ if (writable) {
pa_usec_t time_passed;
pa_usec_t audio_sent;
@@ -1061,6 +1049,7 @@ static void thread_func(void *userdata) {
if (audio_sent <= time_passed) {
pa_usec_t audio_to_send = time_passed - audio_sent;
+ size_t bytes_to_send = bytes_to_send = pa_usec_to_bytes(audio_to_send, &u->sample_spec);
/* Never try to catch up for more than 100ms */
if (u->write_index > 0 && audio_to_send > MAX_PLAYBACK_CATCH_UP_USEC) {
@@ -1080,14 +1069,14 @@ static void thread_func(void *userdata) {
pa_sink_render_full(u->sink, skip_bytes, &tmp);
pa_memblock_unref(tmp.memblock);
u->write_index += skip_bytes;
+ bytes_to_send -= skip_bytes;
if (u->profile == PROFILE_A2DP)
a2dp_reduce_bitpool(u);
}
}
- do_write = 1;
- pending_read_bytes = 0;
+ do_write = bytes_to_send / u->write_block_size;
}
}
@@ -1169,8 +1158,6 @@ io_fail:
if (!pollfd || (pollfd->revents & POLLHUP) == 0)
goto fail;
- do_write = 0;
- pending_read_bytes = 0;
writable = false;
teardown_stream(u);
--
1.8.1.4
More information about the pulseaudio-discuss
mailing list