Skip to content

Commit

Permalink
Always keep CVSD read buffer bigger than read MTU
Browse files Browse the repository at this point in the history
Read less data than the SCO MTU might cause issues with prompt SCO
buffer flushing, which in turn might cause audio issues.

Fixes #510
  • Loading branch information
arkq committed Nov 15, 2021
1 parent 24b7300 commit 2957e71
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 12 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

AC_PREREQ([2.60])
AC_INIT([BlueALSA],
[m4_normalize(esyscmd([test -d .git && git describe || echo v3.1.0]))],
[m4_normalize(esyscmd([test -d .git && git describe --always --dirty || echo v3.1.0]))],
[[email protected]], [bluez-alsa], [https://github.com/Arkq/bluez-alsa])
AM_INIT_AUTOMAKE([foreign subdir-objects -Wall -Werror])

Expand Down
13 changes: 7 additions & 6 deletions src/a2dp-aac.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,14 +404,15 @@ static void *a2dp_aac_dec_thread(struct ba_transport_thread *th) {
}

if (ffb_len_in(&latm) < rtp_latm_len) {
debug("Resizing LATM buffer: %zd -> %zd", latm.size, latm.size + t->mtu_read);
size_t prev_len = ffb_len_out(&latm);
ffb_init_uint8_t(&latm, latm.nmemb + t->mtu_read);
ffb_seek(&latm, prev_len);
debug("Resizing LATM buffer: %zd -> %zd", latm.nmemb, latm.nmemb + t->mtu_read);
if (ffb_init_uint8_t(&latm, latm.nmemb + t->mtu_read) == -1)
error("Couldn't resize LATM buffer: %s", strerror(errno));
}

memcpy(latm.tail, rtp_latm, rtp_latm_len);
ffb_seek(&latm, rtp_latm_len);
if (ffb_len_in(&latm) >= rtp_latm_len) {
memcpy(latm.tail, rtp_latm, rtp_latm_len);
ffb_seek(&latm, rtp_latm_len);
}

if (markbit_quirk != 1 && !rtp_header->markbit) {
debug("Fragmented RTP packet [%u]: LATM len: %zd", rtp_seq_number, rtp_latm_len);
Expand Down
12 changes: 11 additions & 1 deletion src/sco.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,13 @@ static void *sco_cvsd_dec_thread(struct ba_transport_thread *th) {
struct ba_transport_pcm *pcm = &t->sco.mic_pcm;
struct io_poll io = { .timeout = -1 };

const size_t mtu_samples = t->mtu_read / sizeof(int16_t);
const size_t mtu_samples_multiplier = 2;

ffb_t buffer = { 0 };
pthread_cleanup_push(PTHREAD_CLEANUP(ffb_free), &buffer);

if (ffb_init_int16_t(&buffer, t->mtu_read) == -1) {
if (ffb_init_int16_t(&buffer, mtu_samples * mtu_samples_multiplier) == -1) {
error("Couldn't create data buffers: %s", strerror(errno));
goto fail_ffb;
}
Expand All @@ -303,6 +306,13 @@ static void *sco_cvsd_dec_thread(struct ba_transport_thread *th) {
else if (len == 0)
goto exit;

if ((size_t)len == buffer.nmemb * buffer.size) {
debug("Resizing CVSD read buffer: %zd -> %zd",
buffer.nmemb * buffer.size, buffer.nmemb * buffer.size * 2);
if (ffb_init_int16_t(&buffer, buffer.nmemb * 2) == -1)
error("Couldn't resize CVSD read buffer: %s", strerror(errno));
}

if (!ba_transport_pcm_is_active(pcm))
continue;

Expand Down
7 changes: 5 additions & 2 deletions src/shared/ffb.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* BlueALSA - ffb.c
* Copyright (c) 2016-2020 Arkadiusz Bokowy
* Copyright (c) 2016-2021 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
Expand All @@ -26,7 +26,10 @@ int ffb_init(ffb_t *ffb, size_t nmemb, size_t size) {
if ((ptr = realloc(ffb->data, nmemb * size)) == NULL)
return -1;

ffb->data = ffb->tail = ptr;
size_t len = ffb_blen_out(ffb);

ffb->data = ptr;
ffb->tail = (uint8_t *)ptr + len;
ffb->nmemb = nmemb;
ffb->size = size;

Expand Down
29 changes: 27 additions & 2 deletions test/test-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ START_TEST(test_difftimespec) {

} END_TEST

START_TEST(test_fifo_buffer) {
START_TEST(test_ffb) {

ffb_t ffb_u8 = { 0 };
ffb_t ffb_16 = { 0 };
Expand Down Expand Up @@ -241,6 +241,29 @@ START_TEST(test_fifo_buffer) {

} END_TEST

START_TEST(test_ffb_resize) {

const char *data = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const size_t data_len = strlen(data);

ffb_t ffb = { 0 };
ck_assert_int_eq(ffb_init_uint8_t(&ffb, 64), 0);

memcpy(ffb.data, data, data_len);
ffb_seek(&ffb, data_len);

ck_assert_int_eq(ffb_len_out(&ffb), data_len);
ck_assert_int_eq(ffb_len_in(&ffb), 64 - data_len);
ck_assert_int_eq(memcmp(ffb.data, data, data_len), 0);

ck_assert_int_eq(ffb_init_uint8_t(&ffb, 128), 0);

ck_assert_int_eq(ffb_len_out(&ffb), data_len);
ck_assert_int_eq(ffb_len_in(&ffb), 128 - data_len);
ck_assert_int_eq(memcmp(ffb.data, data, data_len), 0);

} END_TEST

int main(void) {

Suite *s = suite_create(__FILE__);
Expand All @@ -255,7 +278,9 @@ int main(void) {
tcase_add_test(tc, test_g_variant_sanitize_object_path);
tcase_add_test(tc, test_batostr_);
tcase_add_test(tc, test_difftimespec);
tcase_add_test(tc, test_fifo_buffer);

tcase_add_test(tc, test_ffb);
tcase_add_test(tc, test_ffb_resize);

srunner_run_all(sr, CK_ENV);
int nf = srunner_ntests_failed(sr);
Expand Down

0 comments on commit 2957e71

Please sign in to comment.