mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	bluez5: handle remove of devices
Fix a2dp-sink for new scheduling
This commit is contained in:
		
							parent
							
								
									4c9c939527
								
							
						
					
					
						commit
						08484b92f5
					
				
					 2 changed files with 58 additions and 22 deletions
				
			
		| 
						 | 
					@ -300,22 +300,6 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void try_pull(struct impl *this, uint32_t frames, bool do_pull)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct spa_io_buffers *io = this->io;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (spa_list_is_empty(&this->ready) && do_pull) {
 | 
					 | 
				
			||||||
		spa_log_trace(this->log, "a2dp-sink %p: %d", this, io->status);
 | 
					 | 
				
			||||||
		io->status = SPA_STATUS_NEED_BUFFER;
 | 
					 | 
				
			||||||
		if (this->range) {
 | 
					 | 
				
			||||||
			this->range->offset = this->sample_count * this->frame_size;
 | 
					 | 
				
			||||||
			this->range->min_size = this->threshold * this->frame_size;
 | 
					 | 
				
			||||||
			this->range->max_size = frames * this->frame_size;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		this->callbacks->process(this->callbacks_data, SPA_STATUS_NEED_BUFFER);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void calc_timeout(size_t target, size_t current,
 | 
					static inline void calc_timeout(size_t target, size_t current,
 | 
				
			||||||
				size_t rate, struct timespec *now,
 | 
									size_t rate, struct timespec *now,
 | 
				
			||||||
				struct timespec *ts)
 | 
									struct timespec *ts)
 | 
				
			||||||
| 
						 | 
					@ -549,8 +533,6 @@ static int flush_data(struct impl *this, uint64_t now_time)
 | 
				
			||||||
			spa_log_trace(this->log, "a2dp-sink %p: reuse buffer %u", this, b->outbuf->id);
 | 
								spa_log_trace(this->log, "a2dp-sink %p: reuse buffer %u", this, b->outbuf->id);
 | 
				
			||||||
			this->callbacks->reuse_buffer(this->callbacks_data, 0, b->outbuf->id);
 | 
								this->callbacks->reuse_buffer(this->callbacks_data, 0, b->outbuf->id);
 | 
				
			||||||
			this->ready_offset = 0;
 | 
								this->ready_offset = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
			try_pull(this, this->write_samples, true);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		total_frames += n_frames;
 | 
							total_frames += n_frames;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -647,6 +629,7 @@ static void a2dp_on_timeout(struct spa_source *source)
 | 
				
			||||||
	struct impl *this = source->data;
 | 
						struct impl *this = source->data;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	uint64_t exp, now_time;
 | 
						uint64_t exp, now_time;
 | 
				
			||||||
 | 
						struct spa_io_buffers *io = this->io;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->started && read(this->timerfd, &exp, sizeof(uint64_t)) != sizeof(uint64_t))
 | 
						if (this->started && read(this->timerfd, &exp, sizeof(uint64_t)) != sizeof(uint64_t))
 | 
				
			||||||
		spa_log_warn(this->log, "error reading timerfd: %s", strerror(errno));
 | 
							spa_log_warn(this->log, "error reading timerfd: %s", strerror(errno));
 | 
				
			||||||
| 
						 | 
					@ -657,17 +640,28 @@ static void a2dp_on_timeout(struct spa_source *source)
 | 
				
			||||||
	spa_log_trace(this->log, "timeout %ld %ld", now_time, now_time - this->last_time);
 | 
						spa_log_trace(this->log, "timeout %ld %ld", now_time, now_time - this->last_time);
 | 
				
			||||||
	this->last_time = now_time;
 | 
						this->last_time = now_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	try_pull(this, this->write_samples, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (this->start_time == 0) {
 | 
						if (this->start_time == 0) {
 | 
				
			||||||
		if ((err = fill_socket(this, now_time)) < 0)
 | 
							if ((err = fill_socket(this, now_time)) < 0)
 | 
				
			||||||
			spa_log_error(this->log, "error fill socket %s", spa_strerror(err));
 | 
								spa_log_error(this->log, "error fill socket %s", spa_strerror(err));
 | 
				
			||||||
		this->start_time = now_time;
 | 
							this->start_time = now_time;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (spa_list_is_empty(&this->ready)) {
 | 
				
			||||||
 | 
							spa_log_trace(this->log, "a2dp-sink %p: %d", this, io->status);
 | 
				
			||||||
 | 
							io->status = SPA_STATUS_NEED_BUFFER;
 | 
				
			||||||
 | 
							if (this->range) {
 | 
				
			||||||
 | 
								this->range->offset = this->sample_count * this->frame_size;
 | 
				
			||||||
 | 
								this->range->min_size = this->threshold * this->frame_size;
 | 
				
			||||||
 | 
								this->range->max_size = this->write_samples * this->frame_size;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							this->callbacks->process(this->callbacks_data, SPA_STATUS_NEED_BUFFER);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
		flush_data(this, now_time);
 | 
							flush_data(this, now_time);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int init_sbc(struct impl *this)
 | 
					static int init_sbc(struct impl *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
        struct spa_bt_transport *transport = this->transport;
 | 
					        struct spa_bt_transport *transport = this->transport;
 | 
				
			||||||
| 
						 | 
					@ -1270,6 +1264,7 @@ static int impl_node_process(struct spa_node *node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (input->status == SPA_STATUS_HAVE_BUFFER && input->buffer_id < this->n_buffers) {
 | 
						if (input->status == SPA_STATUS_HAVE_BUFFER && input->buffer_id < this->n_buffers) {
 | 
				
			||||||
		struct buffer *b = &this->buffers[input->buffer_id];
 | 
							struct buffer *b = &this->buffers[input->buffer_id];
 | 
				
			||||||
 | 
							uint64_t now_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!b->outstanding) {
 | 
							if (!b->outstanding) {
 | 
				
			||||||
			spa_log_warn(this->log, NAME " %p: buffer %u in use", this, input->buffer_id);
 | 
								spa_log_warn(this->log, NAME " %p: buffer %u in use", this, input->buffer_id);
 | 
				
			||||||
| 
						 | 
					@ -1281,7 +1276,12 @@ static int impl_node_process(struct spa_node *node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spa_list_append(&this->ready, &b->link);
 | 
							spa_list_append(&this->ready, &b->link);
 | 
				
			||||||
		b->outstanding = false;
 | 
							b->outstanding = false;
 | 
				
			||||||
		input->buffer_id = SPA_ID_INVALID;
 | 
					
 | 
				
			||||||
 | 
							clock_gettime(CLOCK_MONOTONIC, &this->now);
 | 
				
			||||||
 | 
							now_time = this->now.tv_sec * SPA_NSEC_PER_SEC + this->now.tv_nsec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							flush_data(this, now_time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		input->status = SPA_STATUS_OK;
 | 
							input->status = SPA_STATUS_OK;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return SPA_STATUS_OK;
 | 
						return SPA_STATUS_OK;
 | 
				
			||||||
| 
						 | 
					@ -1289,6 +1289,7 @@ static int impl_node_process(struct spa_node *node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct spa_dict_item node_info_items[] = {
 | 
					static const struct spa_dict_item node_info_items[] = {
 | 
				
			||||||
	{ "media.class", "Audio/Sink" },
 | 
						{ "media.class", "Audio/Sink" },
 | 
				
			||||||
 | 
					        { "node.driver", "true" },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct spa_dict node_info = {
 | 
					static const struct spa_dict node_info = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -663,6 +663,22 @@ static struct spa_bt_node *node_create(struct spa_bt_monitor *monitor, struct sp
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct spa_bt_node *node_destroy(struct spa_bt_monitor *monitor, struct spa_bt_transport *transport)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct spa_event *event;
 | 
				
			||||||
 | 
						struct spa_pod_builder b = { NULL, };
 | 
				
			||||||
 | 
						uint8_t buffer[4096];
 | 
				
			||||||
 | 
						struct spa_pod *item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_pod_builder_init(&b, buffer, sizeof(buffer));
 | 
				
			||||||
 | 
						event = spa_pod_builder_object(&b, 0, monitor->type.monitor.Removed);
 | 
				
			||||||
 | 
						fill_item(monitor, transport, &item, &b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						monitor->callbacks->event(monitor->callbacks_data, event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int transport_acquire(struct spa_bt_transport *transport, bool optional)
 | 
					static int transport_acquire(struct spa_bt_transport *transport, bool optional)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_monitor *monitor = transport->monitor;
 | 
						struct spa_bt_monitor *monitor = transport->monitor;
 | 
				
			||||||
| 
						 | 
					@ -819,7 +835,26 @@ static DBusHandlerResult endpoint_set_configuration(DBusConnection *conn,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult endpoint_clear_configuration(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult endpoint_clear_configuration(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct spa_bt_monitor *monitor = userdata;
 | 
				
			||||||
 | 
						DBusError err;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
 | 
						const char *transport_path;
 | 
				
			||||||
 | 
						struct spa_bt_transport *transport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbus_error_init(&err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!dbus_message_get_args(m, &err,
 | 
				
			||||||
 | 
									   DBUS_TYPE_OBJECT_PATH, &transport_path,
 | 
				
			||||||
 | 
									   DBUS_TYPE_INVALID)) {
 | 
				
			||||||
 | 
							spa_log_warn(monitor->log, "Bad ClearConfiguration method call: %s",
 | 
				
			||||||
 | 
								err.message);
 | 
				
			||||||
 | 
							dbus_error_free(&err);
 | 
				
			||||||
 | 
							return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						transport = transport_find(monitor, transport_path);
 | 
				
			||||||
 | 
						if (transport != NULL)
 | 
				
			||||||
 | 
							node_destroy(monitor, transport);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((r = dbus_message_new_method_return(m)) == NULL)
 | 
						if ((r = dbus_message_new_method_return(m)) == NULL)
 | 
				
			||||||
		return DBUS_HANDLER_RESULT_NEED_MEMORY;
 | 
							return DBUS_HANDLER_RESULT_NEED_MEMORY;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue