bluez5: handle remove of devices

Fix a2dp-sink for new scheduling
This commit is contained in:
Wim Taymans 2018-04-24 17:02:19 +02:00
parent 4c9c939527
commit 08484b92f5
2 changed files with 58 additions and 22 deletions

View file

@ -300,22 +300,6 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
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,
size_t rate, struct timespec *now,
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);
this->callbacks->reuse_buffer(this->callbacks_data, 0, b->outbuf->id);
this->ready_offset = 0;
try_pull(this, this->write_samples, true);
}
total_frames += n_frames;
@ -647,6 +629,7 @@ static void a2dp_on_timeout(struct spa_source *source)
struct impl *this = source->data;
int err;
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))
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);
this->last_time = now_time;
try_pull(this, this->write_samples, true);
if (this->start_time == 0) {
if ((err = fill_socket(this, now_time)) < 0)
spa_log_error(this->log, "error fill socket %s", spa_strerror(err));
this->start_time = now_time;
}
flush_data(this, 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);
}
}
static int init_sbc(struct impl *this)
{
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) {
struct buffer *b = &this->buffers[input->buffer_id];
uint64_t now_time;
if (!b->outstanding) {
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);
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;
}
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[] = {
{ "media.class", "Audio/Sink" },
{ "node.driver", "true" },
};
static const struct spa_dict node_info = {

View file

@ -663,6 +663,22 @@ static struct spa_bt_node *node_create(struct spa_bt_monitor *monitor, struct sp
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)
{
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)
{
struct spa_bt_monitor *monitor = userdata;
DBusError err;
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)
return DBUS_HANDLER_RESULT_NEED_MEMORY;