mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
bluez5: fix ldac stuttering
Signed-off-by: Huang-Huang Bao <eh5@sokka.cn>
This commit is contained in:
parent
1636e08368
commit
30755c4a44
2 changed files with 28 additions and 9 deletions
|
|
@ -37,6 +37,12 @@
|
||||||
|
|
||||||
#define MAX_FRAME_COUNT 16
|
#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 {
|
struct impl {
|
||||||
HANDLE_LDAC_BT ldac;
|
HANDLE_LDAC_BT ldac;
|
||||||
|
|
||||||
|
|
@ -196,11 +202,15 @@ static int get_frame_length(struct impl *this)
|
||||||
{
|
{
|
||||||
this->eqmid = ldacBT_get_eqmid(this->ldac);
|
this->eqmid = ldacBT_get_eqmid(this->ldac);
|
||||||
switch (this->eqmid) {
|
switch (this->eqmid) {
|
||||||
case LDACBT_EQMID_HQ:
|
case LDACBT_EQMID_BITRATE_990000:
|
||||||
return 330;
|
return 330;
|
||||||
case LDACBT_EQMID_SQ:
|
case LDACBT_EQMID_BITRATE_660000:
|
||||||
return 220;
|
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 110;
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -228,7 +238,7 @@ static int codec_get_num_blocks(void *data)
|
||||||
{
|
{
|
||||||
struct impl *this = data;
|
struct impl *this = data;
|
||||||
size_t rtp_size = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
|
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 */
|
/* frame_count is only 4 bit number */
|
||||||
if (frame_count > 15)
|
if (frame_count > 15)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
written = send(this->flush_source.fd, this->buffer, this->buffer_used, MSG_DONTWAIT | MSG_NOSIGNAL);
|
||||||
reset_buffer(this);
|
reset_buffer(this);
|
||||||
|
|
||||||
spa_log_debug(this->log, NAME " %p: send %d: %m", this, written);
|
spa_log_debug(this->log, NAME " %p: send %d", this, written);
|
||||||
if (written < 0)
|
if (written < 0) {
|
||||||
|
spa_log_debug(this->log, NAME " %p: %m", this);
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool need_flush(struct impl *this)
|
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)
|
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)
|
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);
|
this->buffer_used, this->num_blocks, this->block_size);
|
||||||
|
|
||||||
if (force || need_flush(this))
|
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)
|
static int flush_data(struct impl *this, uint64_t now_time)
|
||||||
{
|
{
|
||||||
int written;
|
int written;
|
||||||
uint32_t total_frames;
|
uint32_t total_frames, iter_buffer_used;
|
||||||
struct port *port = &this->port;
|
struct port *port = &this->port;
|
||||||
|
|
||||||
total_frames = 0;
|
total_frames = 0;
|
||||||
again:
|
again:
|
||||||
|
iter_buffer_used = this->buffer_used;
|
||||||
while (!spa_list_is_empty(&port->ready)) {
|
while (!spa_list_is_empty(&port->ready)) {
|
||||||
uint8_t *src;
|
uint8_t *src;
|
||||||
uint32_t n_bytes, n_frames;
|
uint32_t n_bytes, n_frames;
|
||||||
|
|
@ -510,6 +513,12 @@ again:
|
||||||
spa_log_trace(this->log, NAME " %p: written %u frames", this, total_frames);
|
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);
|
written = flush_buffer(this, true);
|
||||||
if (written == -EAGAIN) {
|
if (written == -EAGAIN) {
|
||||||
spa_log_trace(this->log, NAME" %p: delay flush", this);
|
spa_log_trace(this->log, NAME" %p: delay flush", this);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue