From: Lennart Poettering Date: Thu, 19 Mar 2009 16:46:13 +0000 (+0100) Subject: Merge commit 'elmarco/bluetooth-fixes' X-Git-Url: https://code.delx.au/pulseaudio/commitdiff_plain/4a983124e1ca76f05050e149d6333ec6b6940886?hp=-c Merge commit 'elmarco/bluetooth-fixes' --- 4a983124e1ca76f05050e149d6333ec6b6940886 diff --combined src/modules/bluetooth/module-bluetooth-device.c index 2ae6e111,4df2ca4d..1b61a6fc --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@@ -57,6 -57,9 +57,6 @@@ #define MAX_BITPOOL 64 #define MIN_BITPOOL 2U -#define SOL_SCO 17 -#define SCO_TXBUFS 0x03 -#define SCO_RXBUFS 0x04 PA_MODULE_AUTHOR("Joao Paulo Rechi Vita"); PA_MODULE_DESCRIPTION("Bluetooth audio sink and source"); @@@ -75,10 -78,6 +75,10 @@@ PA_MODULE_USAGE "sco_sink= " "sco_source="); +/* TODO: not close fd when entering suspend mode in a2dp */ + +/* TODO: BT_PCM_FLAG_NREC */ + static const char* const valid_modargs[] = { "name", "card_name", @@@ -161,6 -160,8 +161,8 @@@ struct userdata int service_write_type, service_read_type; }; + #define USE_SCO_OVER_PCM(u) (u->profile == PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source)) + static int init_bt(struct userdata *u); static int init_profile(struct userdata *u); @@@ -654,7 -655,7 +656,7 @@@ static int set_conf(struct userdata *u return 0; } - /* from IO thread */ + /* from IO thread, except in SCO over PCM */ static int start_stream_fd(struct userdata *u) { union { bt_audio_msg_header_t rsp; @@@ -690,6 -691,9 +692,6 @@@ return -1; } -/* setsockopt(u->stream_fd, SOL_SCO, SCO_TXBUFS, &period_count, sizeof(period_count)); */ -/* setsockopt(u->stream_fd, SOL_SCO, SCO_SNDBUF, &period_count, sizeof(period_count)); */ - pa_make_fd_nonblock(u->stream_fd); pa_make_socket_low_delay(u->stream_fd); @@@ -949,7 -953,7 +951,7 @@@ static int a2dp_process_render(struct u void *d; const void *p; unsigned frame_count; - int written; + size_t written; uint64_t writing_at; pa_assert(u); @@@ -975,14 -979,14 +977,14 @@@ writing_at = u->write_index; do { - int encoded; + ssize_t encoded; if (!u->write_memchunk.memblock) pa_sink_render_full(u->sink, u->block_size, &u->write_memchunk); p = (const uint8_t*) pa_memblock_acquire(u->write_memchunk.memblock) + u->write_memchunk.index; encoded = sbc_encode(&a2dp->sbc, - (void*) p, u->write_memchunk.length, + p, u->write_memchunk.length, d, left, &written); @@@ -997,11 -1001,10 +999,11 @@@ return -1; } - pa_assert(written >= 0); - pa_assert((size_t) encoded <= u->write_memchunk.length); + pa_assert((size_t) encoded == sbc_get_codesize(&a2dp->sbc)); + pa_assert((size_t) written <= left); + pa_assert((size_t) written == sbc_get_frame_length(&a2dp->sbc)); /* pa_log_debug("SBC: encoded: %d; written: %d", encoded, written); */ @@@ -1020,7 -1023,7 +1022,7 @@@ frame_count++; - } while ((uint8_t*) d - (uint8_t*) a2dp->buffer + written < (ptrdiff_t) u->link_mtu); + } while (((uint8_t*) d - ((uint8_t*) a2dp->buffer + sbc_get_frame_length(&a2dp->sbc))) < (ptrdiff_t) u->link_mtu); /* write it to the fifo */ memset(a2dp->buffer, 0, sizeof(*header) + sizeof(*payload)); @@@ -1358,8 -1361,6 +1360,6 @@@ static char *get_name(const char *type return pa_sprintf_malloc("bluez_%s.%s", type, n); } - #define USE_SCO_OVER_PCM(u) (u->profile == PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source)) - static void sco_over_pcm_state_update(struct userdata *u) { pa_assert(u); pa_assert(USE_SCO_OVER_PCM(u)); @@@ -1374,11 -1375,14 +1374,14 @@@ if ((init_bt(u) < 0) || (init_profile(u) < 0)) pa_log("Can't resume SCO over PCM"); + start_stream_fd(u); } else { if (u->service_fd < 0) return; + stop_stream_fd(u); + pa_log_debug("Closing SCO over PCM"); pa_close(u->service_fd); u->service_fd = -1; @@@ -1628,15 -1632,19 +1631,19 @@@ static int start_thread(struct userdat pa_assert(!u->rtpoll); pa_assert(!u->rtpoll_item); + u->rtpoll = pa_rtpoll_new(); + pa_thread_mq_init(&u->thread_mq, u->core->mainloop, u->rtpoll); + if (USE_SCO_OVER_PCM(u)) { + if (start_stream_fd(u) < 0) + return -1; + pa_sink_ref(u->sink); pa_source_ref(u->source); + /* FIXME: monitor stream_fd error */ return 0; } - u->rtpoll = pa_rtpoll_new(); - pa_thread_mq_init(&u->thread_mq, u->core->mainloop, u->rtpoll); - if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log_error("Failed to create IO thread"); stop_thread(u);