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