diff --git a/spa/plugins/bluez5/a2dp-codec-ldac.c b/spa/plugins/bluez5/a2dp-codec-ldac.c index eae382f79..84c39e2cb 100644 --- a/spa/plugins/bluez5/a2dp-codec-ldac.c +++ b/spa/plugins/bluez5/a2dp-codec-ldac.c @@ -37,6 +37,12 @@ #define MAX_FRAME_COUNT 16 +#define LDACBT_EQMID_BITRATE_990000 LDACBT_EQMID_HQ +#define LDACBT_EQMID_BITRATE_660000 LDACBT_EQMID_SQ +#define LDACBT_EQMID_BITRATE_330000 LDACBT_EQMID_MQ +#define LDACBT_EQMID_BITRATE_492000 3 +#define LDACBT_EQMID_BITRATE_396000 4 + struct impl { HANDLE_LDAC_BT ldac; @@ -196,11 +202,15 @@ static int get_frame_length(struct impl *this) { this->eqmid = ldacBT_get_eqmid(this->ldac); switch (this->eqmid) { - case LDACBT_EQMID_HQ: + case LDACBT_EQMID_BITRATE_990000: return 330; - case LDACBT_EQMID_SQ: + case LDACBT_EQMID_BITRATE_660000: return 220; - case LDACBT_EQMID_MQ: + case LDACBT_EQMID_BITRATE_492000: + return 164; + case LDACBT_EQMID_BITRATE_396000: + return 132; + case LDACBT_EQMID_BITRATE_330000: return 110; } return -EINVAL; @@ -228,7 +238,7 @@ static int codec_get_num_blocks(void *data) { struct impl *this = data; size_t rtp_size = sizeof(struct rtp_header) + sizeof(struct rtp_payload); - size_t frame_count = (this->mtu - rtp_size) / this->frame_length; + size_t frame_count = SPA_MIN(this->mtu - rtp_size, 660) / this->frame_length; /* frame_count is only 4 bit number */ if (frame_count > 15) diff --git a/spa/plugins/bluez5/a2dp-sink.c b/spa/plugins/bluez5/a2dp-sink.c index 67d375bb0..f5ebbfce2 100644 --- a/spa/plugins/bluez5/a2dp-sink.c +++ b/spa/plugins/bluez5/a2dp-sink.c @@ -346,16 +346,18 @@ static int send_buffer(struct impl *this) written = send(this->flush_source.fd, this->buffer, this->buffer_used, MSG_DONTWAIT | MSG_NOSIGNAL); reset_buffer(this); - spa_log_debug(this->log, NAME " %p: send %d: %m", this, written); - if (written < 0) + spa_log_debug(this->log, NAME " %p: send %d", this, written); + if (written < 0) { + spa_log_debug(this->log, NAME " %p: %m", this); return -errno; + } return written; } static bool need_flush(struct impl *this) { - return (this->frame_count + 1 >= this->num_blocks); + return (this->frame_count >= this->num_blocks); } static int encode_buffer(struct impl *this, const void *data, uint32_t size) @@ -411,7 +413,7 @@ static int encode_buffer(struct impl *this, const void *data, uint32_t size) static int flush_buffer(struct impl *this, bool force) { - spa_log_trace(this->log, NAME" %p: used:%d num_blocks:%d block_size%d", this, + spa_log_trace(this->log, NAME" %p: used:%d num_blocks:%d block_size:%d", this, this->buffer_used, this->num_blocks, this->block_size); if (force || need_flush(this)) @@ -448,11 +450,12 @@ static void enable_flush(struct impl *this, bool enabled) static int flush_data(struct impl *this, uint64_t now_time) { int written; - uint32_t total_frames; + uint32_t total_frames, iter_buffer_used; struct port *port = &this->port; total_frames = 0; again: + iter_buffer_used = this->buffer_used; while (!spa_list_is_empty(&port->ready)) { uint8_t *src; uint32_t n_bytes, n_frames; @@ -510,6 +513,12 @@ again: spa_log_trace(this->log, NAME " %p: written %u frames", this, total_frames); } + iter_buffer_used = this->buffer_used - iter_buffer_used; + if (written > 0 && iter_buffer_used == 0) { + enable_flush(this, false); + return 0; + } + written = flush_buffer(this, true); if (written == -EAGAIN) { spa_log_trace(this->log, NAME" %p: delay flush", this);