mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
media-session: keep track of dsp proxy
Keep the dsp_proxy around because we need it to clean up the session.
This commit is contained in:
parent
4764d69e26
commit
41d38e56df
1 changed files with 49 additions and 36 deletions
|
|
@ -129,8 +129,8 @@ struct session {
|
||||||
|
|
||||||
struct node *node;
|
struct node *node;
|
||||||
struct node *dsp;
|
struct node *dsp;
|
||||||
struct pw_link_proxy *link;
|
struct pw_proxy *dsp_proxy;
|
||||||
struct spa_hook link_listener;
|
struct pw_proxy *link_proxy;
|
||||||
|
|
||||||
struct spa_list node_list;
|
struct spa_list node_list;
|
||||||
|
|
||||||
|
|
@ -139,7 +139,6 @@ struct session {
|
||||||
struct spa_source *idle_timeout;
|
struct spa_source *idle_timeout;
|
||||||
|
|
||||||
bool starting;
|
bool starting;
|
||||||
bool dsp_pending;
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool busy;
|
bool busy;
|
||||||
bool exclusive;
|
bool exclusive;
|
||||||
|
|
@ -217,9 +216,13 @@ static void add_idle_timeout(struct session *sess)
|
||||||
|
|
||||||
static int unlink_session_dsp(struct impl *impl, struct session *session)
|
static int unlink_session_dsp(struct impl *impl, struct session *session)
|
||||||
{
|
{
|
||||||
|
if (session->link_proxy == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (impl->core_proxy)
|
if (impl->core_proxy)
|
||||||
pw_core_proxy_destroy(impl->core_proxy, (struct pw_proxy*)session->link);
|
pw_core_proxy_destroy(impl->core_proxy, session->link_proxy);
|
||||||
session->link = NULL;
|
|
||||||
|
session->link_proxy = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,7 +236,6 @@ static int on_node_idle(struct impl *impl, struct node *node)
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case NODE_TYPE_DSP:
|
case NODE_TYPE_DSP:
|
||||||
pw_log_debug(NAME" %p: dsp idle for session %d", impl, sess->id);
|
pw_log_debug(NAME" %p: dsp idle for session %d", impl, sess->id);
|
||||||
if (sess->link)
|
|
||||||
unlink_session_dsp(impl, sess);
|
unlink_session_dsp(impl, sess);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -254,6 +256,9 @@ static int link_session_dsp(struct impl *impl, struct session *session)
|
||||||
{
|
{
|
||||||
struct pw_properties *props;
|
struct pw_properties *props;
|
||||||
|
|
||||||
|
if (session->link_proxy != NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
pw_log_debug(NAME " %p: link session dsp '%d'", impl, session->id);
|
pw_log_debug(NAME " %p: link session dsp '%d'", impl, session->id);
|
||||||
|
|
||||||
props = pw_properties_new(NULL, NULL);
|
props = pw_properties_new(NULL, NULL);
|
||||||
|
|
@ -271,12 +276,14 @@ static int link_session_dsp(struct impl *impl, struct session *session)
|
||||||
pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1);
|
pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
session->link = pw_core_proxy_create_object(impl->core_proxy,
|
session->link_proxy = pw_core_proxy_create_object(impl->core_proxy,
|
||||||
"link-factory",
|
"link-factory",
|
||||||
PW_TYPE_INTERFACE_Link,
|
PW_TYPE_INTERFACE_Link,
|
||||||
PW_VERSION_LINK,
|
PW_VERSION_LINK,
|
||||||
&props->dict,
|
&props->dict,
|
||||||
0);
|
0);
|
||||||
|
pw_properties_free(props);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,7 +297,6 @@ static int on_node_running(struct impl *impl, struct node *node)
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case NODE_TYPE_DSP:
|
case NODE_TYPE_DSP:
|
||||||
pw_log_debug(NAME" %p: dsp running for session %d", impl, sess->id);
|
pw_log_debug(NAME" %p: dsp running for session %d", impl, sess->id);
|
||||||
if (sess->link == NULL)
|
|
||||||
link_session_dsp(impl, sess);
|
link_session_dsp(impl, sess);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -374,9 +380,14 @@ static void remove_session(struct impl *impl, struct session *sess)
|
||||||
spa_list_remove(&n->session_link);
|
spa_list_remove(&n->session_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sess->dsp && impl->core_proxy) {
|
if (sess->dsp) {
|
||||||
pw_log_debug(NAME " %p: destroy dsp %p", impl, sess->dsp->obj.proxy);
|
sess->dsp->manager = NULL;
|
||||||
pw_core_proxy_destroy(impl->core_proxy, sess->dsp->obj.proxy);
|
}
|
||||||
|
if (sess->dsp_proxy) {
|
||||||
|
pw_log_debug(NAME " %p: destroy dsp %p", impl, sess->dsp_proxy);
|
||||||
|
if (impl->core_proxy)
|
||||||
|
pw_core_proxy_destroy(impl->core_proxy, sess->dsp_proxy);
|
||||||
|
sess->dsp_proxy = NULL;
|
||||||
}
|
}
|
||||||
spa_list_remove(&sess->l);
|
spa_list_remove(&sess->l);
|
||||||
free(sess);
|
free(sess);
|
||||||
|
|
@ -418,12 +429,14 @@ static int
|
||||||
handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
|
handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
|
||||||
uint32_t type, const struct spa_dict *props)
|
uint32_t type, const struct spa_dict *props)
|
||||||
{
|
{
|
||||||
const char *str;
|
const char *str, *media_class;
|
||||||
bool need_dsp = false;
|
bool need_dsp = false;
|
||||||
enum pw_direction direction;
|
enum pw_direction direction;
|
||||||
struct pw_proxy *p;
|
struct pw_proxy *p;
|
||||||
struct node *node;
|
struct node *node;
|
||||||
|
|
||||||
|
media_class = props ? spa_dict_lookup(props, "media.class") : NULL;
|
||||||
|
|
||||||
p = pw_registry_proxy_bind(impl->registry_proxy,
|
p = pw_registry_proxy_bind(impl->registry_proxy,
|
||||||
id, type, PW_VERSION_NODE,
|
id, type, PW_VERSION_NODE,
|
||||||
sizeof(struct node));
|
sizeof(struct node));
|
||||||
|
|
@ -441,20 +454,17 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
|
||||||
spa_list_append(&impl->node_list, &node->l);
|
spa_list_append(&impl->node_list, &node->l);
|
||||||
node->type = NODE_TYPE_UNKNOWN;
|
node->type = NODE_TYPE_UNKNOWN;
|
||||||
|
|
||||||
if (props == NULL)
|
if (media_class == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((str = spa_dict_lookup(props, "media.class")) == NULL)
|
pw_log_debug(NAME" %p: node media.class %s", impl, media_class);
|
||||||
return 0;
|
|
||||||
|
|
||||||
pw_log_debug(NAME" %p: node media.class %s", impl, str);
|
if (strstr(media_class, "Stream/") == media_class) {
|
||||||
|
media_class += strlen("Stream/");
|
||||||
|
|
||||||
if (strstr(str, "Stream/") == str) {
|
if (strstr(media_class, "Output/") == media_class)
|
||||||
str += strlen("Stream/");
|
|
||||||
|
|
||||||
if (strstr(str, "Output/") == str)
|
|
||||||
direction = PW_DIRECTION_OUTPUT;
|
direction = PW_DIRECTION_OUTPUT;
|
||||||
else if (strstr(str, "Input/") == str)
|
else if (strstr(media_class, "Input/") == media_class)
|
||||||
direction = PW_DIRECTION_INPUT;
|
direction = PW_DIRECTION_INPUT;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -470,19 +480,19 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
|
||||||
else {
|
else {
|
||||||
struct session *sess;
|
struct session *sess;
|
||||||
|
|
||||||
if (strstr(str, "Audio/") == str) {
|
if (strstr(media_class, "Audio/") == media_class) {
|
||||||
need_dsp = true;
|
need_dsp = true;
|
||||||
str += strlen("Audio/");
|
media_class += strlen("Audio/");
|
||||||
}
|
}
|
||||||
else if (strstr(str, "Video/") == str) {
|
else if (strstr(media_class, "Video/") == media_class) {
|
||||||
str += strlen("Video/");
|
media_class += strlen("Video/");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (strcmp(str, "Sink") == 0)
|
if (strcmp(media_class, "Sink") == 0)
|
||||||
direction = PW_DIRECTION_OUTPUT;
|
direction = PW_DIRECTION_OUTPUT;
|
||||||
else if (strcmp(str, "Source") == 0)
|
else if (strcmp(media_class, "Source") == 0)
|
||||||
direction = PW_DIRECTION_INPUT;
|
direction = PW_DIRECTION_INPUT;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -732,12 +742,13 @@ static int find_session(void *data, struct session *sess)
|
||||||
static int link_nodes(struct node *peer, enum pw_direction direction, struct node *node)
|
static int link_nodes(struct node *peer, enum pw_direction direction, struct node *node)
|
||||||
{
|
{
|
||||||
struct impl *impl = peer->obj.impl;
|
struct impl *impl = peer->obj.impl;
|
||||||
struct pw_properties *props;
|
|
||||||
struct port *p;
|
struct port *p;
|
||||||
|
|
||||||
pw_log_debug(NAME " %p: link nodes %d %d", impl, node->obj.id, peer->obj.id);
|
pw_log_debug(NAME " %p: link nodes %d %d", impl, node->obj.id, peer->obj.id);
|
||||||
|
|
||||||
spa_list_for_each(p, &peer->port_list, l) {
|
spa_list_for_each(p, &peer->port_list, l) {
|
||||||
|
struct pw_properties *props;
|
||||||
|
|
||||||
if (p->direction == direction)
|
if (p->direction == direction)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -766,6 +777,8 @@ static int link_nodes(struct node *peer, enum pw_direction direction, struct nod
|
||||||
PW_VERSION_LINK,
|
PW_VERSION_LINK,
|
||||||
&props->dict,
|
&props->dict,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
pw_properties_free(props);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -876,7 +889,7 @@ static int rescan_node(struct impl *impl, struct node *node)
|
||||||
pw_log_warn(NAME" %p: session %d busy, can't get exclusive access", impl, session->id);
|
pw_log_warn(NAME" %p: session %d busy, can't get exclusive access", impl, session->id);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
if (session->link != NULL) {
|
if (session->link_proxy != NULL) {
|
||||||
pw_log_warn(NAME" %p: session %d busy with DSP", impl, session->id);
|
pw_log_warn(NAME" %p: session %d busy with DSP", impl, session->id);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
@ -928,10 +941,9 @@ static const struct pw_node_proxy_events dsp_node_events = {
|
||||||
|
|
||||||
static void rescan_session(struct impl *impl, struct session *sess)
|
static void rescan_session(struct impl *impl, struct session *sess)
|
||||||
{
|
{
|
||||||
if (sess->need_dsp && sess->dsp == NULL && !sess->dsp_pending) {
|
if (sess->need_dsp && sess->dsp == NULL && sess->dsp_proxy == NULL) {
|
||||||
struct pw_properties *props;
|
struct pw_properties *props;
|
||||||
struct node *node = sess->node;
|
struct node *node = sess->node;
|
||||||
void *dsp;
|
|
||||||
int i;
|
int i;
|
||||||
uint64_t mask = 0;
|
uint64_t mask = 0;
|
||||||
|
|
||||||
|
|
@ -950,14 +962,15 @@ static void rescan_session(struct impl *impl, struct session *sess)
|
||||||
|
|
||||||
pw_log_debug(NAME" %p: making audio dsp for session %d", impl, sess->id);
|
pw_log_debug(NAME" %p: making audio dsp for session %d", impl, sess->id);
|
||||||
|
|
||||||
dsp = pw_core_proxy_create_object(impl->core_proxy,
|
sess->dsp_proxy = pw_core_proxy_create_object(impl->core_proxy,
|
||||||
"audio-dsp",
|
"audio-dsp",
|
||||||
PW_TYPE_INTERFACE_Node,
|
PW_TYPE_INTERFACE_Node,
|
||||||
PW_VERSION_NODE,
|
PW_VERSION_NODE,
|
||||||
&props->dict,
|
&props->dict,
|
||||||
0);
|
0);
|
||||||
sess->dsp_pending = true;
|
pw_properties_free(props);
|
||||||
pw_proxy_add_proxy_listener(dsp, &sess->listener, &dsp_node_events, sess);
|
|
||||||
|
pw_proxy_add_proxy_listener(sess->dsp_proxy, &sess->listener, &dsp_node_events, sess);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sess->starting = false;
|
sess->starting = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue