bluez5: emit & remove the A2DP source node depending on transport state

Typically a source stops the connection when it has nothing to play
and this causes the transport to become "idle" and our A2DP source
also stops. However, the node is still present and "running" (if linked),
which causes the graph to underrun as it receives no data from this node.

This patch dynamically creates and destroys the a2dp source node depending
on the transport state. So, when the transport is idle, there is no node
in the graph at all.
This commit is contained in:
George Kiagiadakis 2021-03-17 22:00:44 +02:00 committed by Wim Taymans
parent c81d44e8a9
commit a75fe69c8e
2 changed files with 84 additions and 46 deletions

View file

@ -107,7 +107,6 @@ struct impl {
struct props props;
struct spa_bt_transport *transport;
struct spa_hook transport_listener;
struct port port;
@ -1165,45 +1164,6 @@ static const struct spa_node_methods impl_node = {
.process = impl_node_process,
};
static int do_transport_destroy(struct spa_loop *loop,
bool async,
uint32_t seq,
const void *data,
size_t size,
void *user_data)
{
struct impl *this = user_data;
this->transport = NULL;
this->transport_acquired = false;
return 0;
}
static void transport_destroy(void *data)
{
struct impl *this = data;
spa_log_debug(this->log, "transport %p destroy", this->transport);
spa_loop_invoke(this->data_loop, do_transport_destroy, 0, NULL, 0, true, this);
}
static void transport_state_changed(void *data, enum spa_bt_transport_state old,
enum spa_bt_transport_state state)
{
struct impl *this = data;
spa_log_debug(this->log, "transport %p state %d->%d started:%d",
this->transport, old, state, this->started);
if (state >= SPA_BT_TRANSPORT_STATE_PENDING && old < SPA_BT_TRANSPORT_STATE_PENDING)
transport_start(this);
else if (state < SPA_BT_TRANSPORT_STATE_PENDING && old >= SPA_BT_TRANSPORT_STATE_PENDING)
transport_stop(this);
}
static const struct spa_bt_transport_events transport_events = {
SPA_VERSION_BT_TRANSPORT_EVENTS,
.destroy = transport_destroy,
.state_changed = transport_state_changed,
};
static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
{
struct impl *this;
@ -1226,8 +1186,6 @@ static int impl_clear(struct spa_handle *handle)
struct impl *this = (struct impl *) handle;
if (this->codec_data)
this->codec->deinit(this->codec_data);
if (this->transport)
spa_hook_remove(&this->transport_listener);
return 0;
}
@ -1325,9 +1283,6 @@ impl_init(const struct spa_handle_factory *factory,
}
this->codec = this->transport->a2dp_codec;
spa_bt_transport_add_listener(this->transport,
&this->transport_listener, &transport_events, this);
return 0;
}