diff --git a/src/examples/media-session.c b/src/examples/media-session.c index 4a3ef77b1..19fccc6bc 100644 --- a/src/examples/media-session.c +++ b/src/examples/media-session.c @@ -42,6 +42,8 @@ #define DEFAULT_CHANNELS 2 #define DEFAULT_SAMPLERATE 48000 +#define DEFAULT_IDLE_SECONDS 3 + #define MIN_QUANTUM_SIZE 64 #define MAX_QUANTUM_SIZE 1024 @@ -86,6 +88,7 @@ struct node { struct spa_list session_link; struct session *session; + struct session *manager; struct spa_list port_list; enum pw_direction direction; @@ -126,7 +129,8 @@ struct session { struct node *node; struct node *dsp; - struct link *link; + struct pw_link_proxy *link; + struct spa_hook link_listener; struct spa_list node_list; @@ -173,18 +177,152 @@ static void schedule_rescan(struct impl *impl) static void remove_idle_timeout(struct session *sess) { struct impl *impl = sess->impl; + struct pw_loop *main_loop = pw_core_get_main_loop(impl->core); if (sess->idle_timeout) { - pw_loop_destroy_source(pw_core_get_main_loop(impl->core), sess->idle_timeout); + pw_loop_destroy_source(main_loop, sess->idle_timeout); sess->idle_timeout = NULL; } } +static void idle_timeout(void *data, uint64_t expirations) +{ + struct session *sess = data; + struct impl *impl = sess->impl; + struct spa_command *cmd = &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Suspend); + + pw_log_debug(NAME " %p: session %d idle timeout", impl, sess->id); + + remove_idle_timeout(sess); + + pw_node_proxy_send_command((struct pw_node_proxy*)sess->node->obj.proxy, cmd); + if (sess->dsp) + pw_node_proxy_send_command((struct pw_node_proxy*)sess->dsp->obj.proxy, cmd); +} + +static void add_idle_timeout(struct session *sess) +{ + struct timespec value; + struct impl *impl = sess->impl; + struct pw_loop *main_loop = pw_core_get_main_loop(impl->core); + + if (sess->idle_timeout == NULL) + sess->idle_timeout = pw_loop_add_timer(main_loop, idle_timeout, sess); + + value.tv_sec = DEFAULT_IDLE_SECONDS; + value.tv_nsec = 0; + pw_loop_update_timer(main_loop, sess->idle_timeout, &value, NULL, false); +} + +static int unlink_session_dsp(struct impl *impl, struct session *session) +{ + pw_core_proxy_destroy(impl->core_proxy, (struct pw_proxy*)session->link); + session->link = NULL; + return 0; +} + +static int on_node_idle(struct impl *impl, struct node *node) +{ + struct session *sess = node->manager; + + if (sess == NULL) + return 0; + + switch (node->type) { + case NODE_TYPE_DSP: + pw_log_debug(NAME" %p: dsp idle for session %d", impl, sess->id); + if (sess->link) + unlink_session_dsp(impl, sess); + break; + + case NODE_TYPE_DEVICE: + pw_log_debug(NAME" %p: device idle for session %d", impl, sess->id); + sess->busy = false; + sess->exclusive = false; + add_idle_timeout(sess); + break; + default: + break; + } + return 0; +} + + +static int link_session_dsp(struct impl *impl, struct session *session) +{ + struct pw_properties *props; + + pw_log_debug(NAME " %p: link session dsp '%d'", impl, session->id); + + props = pw_properties_new(NULL, NULL); +// pw_properties_set(props, PW_LINK_PROP_PASSIVE, "true"); + if (session->direction == PW_DIRECTION_OUTPUT) { + pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", session->dsp->info->id); + pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", -1); + pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", session->node->info->id); + pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1); + } + else { + pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", session->node->info->id); + pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", -1); + pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", session->dsp->info->id); + pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1); + } + + session->link = pw_core_proxy_create_object(impl->core_proxy, + "link-factory", + PW_TYPE_INTERFACE_Link, + PW_VERSION_LINK, + &props->dict, + 0); + return 0; +} + +static int on_node_running(struct impl *impl, struct node *node) +{ + struct session *sess = node->manager; + + if (sess == NULL) + return 0; + + switch (node->type) { + case NODE_TYPE_DSP: + pw_log_debug(NAME" %p: dsp running for session %d", impl, sess->id); + if (sess->link == NULL) + link_session_dsp(impl, sess); + break; + + case NODE_TYPE_DEVICE: + pw_log_debug(NAME" %p: device running or session %d", impl, sess->id); + remove_idle_timeout(sess); + break; + default: + break; + } + return 0; +} + static void node_event_info(void *object, struct pw_node_info *info) { struct node *n = object; - pw_log_debug(NAME" %p: info for node %d", n->obj.impl, n->obj.id); + struct impl *impl = n->obj.impl; + + pw_log_debug(NAME" %p: info for node %d type %d", impl, n->obj.id, n->type); n->info = pw_node_info_update(n->info, info); + + switch (info->state) { + case PW_NODE_STATE_IDLE: + on_node_idle(impl, n); + break; + case PW_NODE_STATE_RUNNING: + on_node_running(impl, n); + break; + case PW_NODE_STATE_SUSPENDED: + break; + default: + break; + } + } static const struct pw_node_proxy_events node_events = { @@ -299,6 +437,7 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id, node->direction = direction; node->type = NODE_TYPE_DEVICE; + node->manager = sess; pw_log_debug(NAME" %p: new session for device node %d", impl, id); } @@ -432,42 +571,49 @@ registry_global(void *data,uint32_t id, uint32_t parent_id, schedule_rescan(impl); } +static void remove_session(struct impl *impl, struct session *sess) +{ + struct node *n, *t; + + pw_log_debug(NAME " %p: remove session '%d'", impl, sess->id); + remove_idle_timeout(sess); + + spa_list_for_each_safe(n, t, &sess->node_list, session_link) { + n->session = NULL; + spa_list_remove(&n->session_link); + } + + if (sess->dsp) { + pw_log_debug(NAME " %p: destroy dsp", impl); + pw_core_proxy_destroy(impl->core_proxy, sess->dsp->obj.proxy); + } + spa_list_remove(&sess->l); + free(sess); +} + static void registry_global_remove(void *data, uint32_t id) { struct impl *impl = data; struct object *obj; - struct session *sess; pw_log_debug(NAME " %p: remove global '%d'", impl, id); if ((obj = find_object(impl, id)) == NULL) return; - spa_list_for_each(sess, &impl->session_list, l) { - struct node *node = (struct node *)obj, *n, *t; + switch (obj->type) { + case PW_TYPE_INTERFACE_Node: + { + struct node *node = (struct node*) obj; + if (node->manager) + remove_session(impl, node->manager); + break; - if (sess->node != node) - continue; - - pw_log_debug(NAME " %p: remove session '%d'", impl, sess->id); - remove_idle_timeout(sess); - - spa_list_for_each_safe(n, t, &sess->node_list, session_link) { - n->session = NULL; - spa_list_remove(&n->session_link); - } - - if (sess->dsp) { - uint32_t id = ((struct object *)sess->dsp)->id; - pw_log_debug(NAME " %p: destroy dsp '%d'", impl, id); - pw_core_proxy_destroy(impl->core_proxy, id); - } - spa_list_remove(&sess->l); - free(sess); + } + default: break; } - remove_object(impl, obj); schedule_rescan(impl); } @@ -479,39 +625,6 @@ static const struct pw_registry_proxy_events registry_events = { }; -static int link_session_dsp(struct session *session) -{ - struct impl *impl = session->impl; - struct pw_properties *props; - - pw_log_debug(NAME " %p: link session dsp '%d'", impl, session->id); - - props = pw_properties_new(NULL, NULL); - pw_properties_set(props, PW_LINK_PROP_PASSIVE, "true"); - if (session->direction == PW_DIRECTION_OUTPUT) { - pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", session->dsp->info->id); - pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", -1); - pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", session->node->info->id); - pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1); - } - else { - pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", session->node->info->id); - pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", -1); - pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", session->dsp->info->id); - pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", -1); - } - - session->link = pw_core_proxy_create_object(impl->core_proxy, - "link-factory", - PW_TYPE_INTERFACE_Link, - PW_VERSION_LINK, - &props->dict, - 0); - return 0; -} - - - struct find_data { struct impl *impl; uint32_t path_id; @@ -618,7 +731,6 @@ static int rescan_node(struct impl *impl, struct node *node) struct pw_node_info *info; struct node *peer; enum pw_direction direction; - int res; if (node->type == NODE_TYPE_DSP || node->type == NODE_TYPE_DEVICE) return 0; @@ -722,10 +834,6 @@ static int rescan_node(struct impl *impl, struct node *node) session->exclusive = exclusive; } else { - if (session->link == NULL) { - if ((res = link_session_dsp(session)) < 0) - return res; - } peer = session->dsp; } @@ -734,7 +842,6 @@ static int rescan_node(struct impl *impl, struct node *node) session->busy = true; node->session = session; spa_list_append(&session->node_list, &node->session_link); - remove_idle_timeout(session); link_nodes(peer, direction, node); @@ -756,6 +863,7 @@ static void dsp_node_event_info(void *object, struct pw_node_info *info) dsp->direction = s->direction; dsp->type = NODE_TYPE_DSP; + dsp->manager = s; } static const struct pw_node_proxy_events dsp_node_events = { @@ -763,36 +871,8 @@ static const struct pw_node_proxy_events dsp_node_events = { .info = dsp_node_event_info, }; -static void idle_timeout(void *data, uint64_t expirations) -{ - struct session *sess = data; - struct impl *impl = sess->impl; - struct spa_command *cmd = &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Suspend); - - pw_log_debug(NAME " %p: session %d idle timeout", impl, sess->id); - - remove_idle_timeout(sess); - - pw_node_proxy_send_command((struct pw_node_proxy*)sess->node->obj.proxy, cmd); - if (sess->dsp) - pw_node_proxy_send_command((struct pw_node_proxy*)sess->dsp->obj.proxy, cmd); -} - static void rescan_session(struct impl *impl, struct session *sess) { - if (spa_list_is_empty(&sess->node_list) && sess->busy) { - struct pw_loop *main_loop = pw_core_get_main_loop(impl->core); - struct timespec value; - - pw_log_debug(NAME "%p: session %d became idle", impl, sess->id); - sess->exclusive = false; - sess->busy = false; - - sess->idle_timeout = pw_loop_add_timer(main_loop, idle_timeout, sess); - value.tv_sec = 3; - value.tv_nsec = 0; - pw_loop_update_timer(main_loop, sess->idle_timeout, &value, NULL, false); - } if (sess->need_dsp && sess->dsp == NULL && !sess->dsp_pending) { struct pw_properties *props; struct node *node = sess->node; diff --git a/src/extensions/client-node.h b/src/extensions/client-node.h index fc552a4e5..97f482aaa 100644 --- a/src/extensions/client-node.h +++ b/src/extensions/client-node.h @@ -58,8 +58,7 @@ struct pw_client_node_position { #define PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE 2 #define PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE 3 #define PW_CLIENT_NODE_PROXY_METHOD_EVENT 4 -#define PW_CLIENT_NODE_PROXY_METHOD_DESTROY 5 -#define PW_CLIENT_NODE_PROXY_METHOD_NUM 6 +#define PW_CLIENT_NODE_PROXY_METHOD_NUM 5 /** \ref pw_client_node methods */ struct pw_client_node_proxy_methods { @@ -120,10 +119,6 @@ struct pw_client_node_proxy_methods { * \param event the event to send */ void (*event) (void *object, struct spa_event *event); - /** - * Destroy the client_node - */ - void (*destroy) (void *object); }; static inline void @@ -176,13 +171,6 @@ pw_client_node_proxy_event(struct pw_client_node_proxy *p, struct spa_event *eve pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, event, event); } -static inline void -pw_client_node_proxy_destroy(struct pw_client_node_proxy *p) -{ - pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, destroy); -} - - #define PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM 0 #define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 1 #define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 2 diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 659e6f5a6..da7b6cb5b 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -1086,12 +1086,6 @@ static void client_node_event(void *data, struct spa_event *event) this->callbacks->event(this->callbacks_data, event); } -static void client_node_destroy(void *data) -{ - struct impl *impl = data; - pw_client_node_destroy(&impl->this); -} - static struct pw_client_node_proxy_methods client_node_methods = { PW_VERSION_CLIENT_NODE_PROXY_METHODS, .done = client_node_done, @@ -1099,7 +1093,6 @@ static struct pw_client_node_proxy_methods client_node_methods = { .port_update = client_node_port_update, .set_active = client_node_set_active, .event = client_node_event, - .destroy = client_node_destroy, }; static void node_on_data_fd_events(struct spa_source *source) diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index 9daf59a2e..674a775cd 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -153,18 +153,6 @@ static void client_node_marshal_event_method(void *object, struct spa_event *eve pw_protocol_native_end_proxy(proxy, b); } -static void client_node_marshal_destroy(void *object) -{ - struct pw_proxy *proxy = object; - struct spa_pod_builder *b; - - b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_DESTROY); - - spa_pod_builder_add_struct(b); - - pw_protocol_native_end_proxy(proxy, b); -} - static int client_node_demarshal_add_mem(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; @@ -874,27 +862,13 @@ static int client_node_demarshal_event_method(void *object, void *data, size_t s return 0; } -static int client_node_demarshal_destroy(void *object, void *data, size_t size) -{ - struct pw_resource *resource = object; - struct spa_pod_parser prs; - - spa_pod_parser_init(&prs, data, size, 0); - if (spa_pod_parser_get(&prs, "[", NULL) < 0) - return -EINVAL; - - pw_resource_do(resource, struct pw_client_node_proxy_methods, destroy, 0); - return 0; -} - static const struct pw_client_node_proxy_methods pw_protocol_native_client_node_method_marshal = { PW_VERSION_CLIENT_NODE_PROXY_METHODS, &client_node_marshal_done, &client_node_marshal_update, &client_node_marshal_port_update, &client_node_marshal_set_active, - &client_node_marshal_event_method, - &client_node_marshal_destroy + &client_node_marshal_event_method }; static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_method_demarshal[] = { @@ -902,8 +876,7 @@ static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_ { &client_node_demarshal_update, 0 }, { &client_node_demarshal_port_update, 0 }, { &client_node_demarshal_set_active, 0 }, - { &client_node_demarshal_event_method, 0 }, - { &client_node_demarshal_destroy, 0 }, + { &client_node_demarshal_event_method, 0 } }; static const struct pw_client_node_proxy_events pw_protocol_native_client_node_event_marshal = { diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 257c831c3..b92dbac7c 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -509,6 +509,22 @@ static int registry_demarshal_bind(void *object, void *data, size_t size) return 0; } +static int registry_demarshal_destroy(void *object, void *data, size_t size) +{ + struct pw_resource *resource = object; + struct spa_pod_parser prs; + uint32_t id; + + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &id, NULL) < 0) + return -EINVAL; + + pw_resource_do(resource, struct pw_registry_proxy_methods, destroy, 0, id); + return 0; +} + static void module_marshal_info(void *object, struct pw_module_info *info) { struct pw_resource *resource = object; @@ -1127,6 +1143,17 @@ static void registry_marshal_bind(void *object, uint32_t id, pw_protocol_native_end_proxy(proxy, b); } +static void registry_marshal_destroy(void *object, uint32_t id) +{ + struct pw_proxy *proxy = object; + struct spa_pod_builder *b; + + b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_DESTROY); + spa_pod_builder_add_struct(b, + "i", id); + pw_protocol_native_end_proxy(proxy, b); +} + static const struct pw_core_proxy_methods pw_protocol_native_core_method_marshal = { PW_VERSION_CORE_PROXY_METHODS, &core_marshal_hello, @@ -1177,10 +1204,12 @@ static const struct pw_protocol_marshal pw_protocol_native_core_marshal = { static const struct pw_registry_proxy_methods pw_protocol_native_registry_method_marshal = { PW_VERSION_REGISTRY_PROXY_METHODS, ®istry_marshal_bind, + ®istry_marshal_destroy, }; static const struct pw_protocol_native_demarshal pw_protocol_native_registry_method_demarshal[] = { { ®istry_demarshal_bind, 0, }, + { ®istry_demarshal_destroy, 0, }, }; static const struct pw_registry_proxy_events pw_protocol_native_registry_event_marshal = { diff --git a/src/pipewire/core.c b/src/pipewire/core.c index 812c592f9..c7364af90 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -89,9 +89,38 @@ static void registry_bind(void *object, uint32_t id, pw_core_resource_remove_id(client->core_resource, new_id); } +static void registry_destroy(void *object, uint32_t id) +{ + struct pw_resource *resource = object; + struct pw_client *client = resource->client; + struct pw_core *core = resource->core; + struct pw_global *global; + uint32_t permissions; + + if ((global = pw_core_find_global(core, id)) == NULL) + goto no_id; + + permissions = pw_global_get_permissions(global, client); + + if (!PW_PERM_IS_X(permissions)) + goto no_id; + + pw_log_debug("global %p: destroy global id %d", global, id); + + pw_global_destroy(global); + return; + + no_id: + pw_log_debug("registry %p: no global with id %u to destroy", resource, id); + goto exit; + exit: + return; +} + static const struct pw_registry_proxy_methods registry_methods = { PW_VERSION_REGISTRY_PROXY_METHODS, - .bind = registry_bind + .bind = registry_bind, + .destroy = registry_destroy }; static void destroy_registry_resource(void *object) @@ -254,16 +283,24 @@ core_create_object(void *object, static void core_destroy(void *object, uint32_t id) { struct pw_resource *resource = object; - struct pw_core *this = resource->core; - struct pw_global *global; + struct pw_client *client = resource->client; + struct pw_resource *r; pw_log_debug("core %p: destroy %d from resource %p", resource->core, id, resource); - global = pw_core_find_global(this, id); - if (global == NULL) - return; + if ((r = pw_client_find_resource(client, id)) == NULL) + goto no_resource; - pw_global_destroy(global); + pw_resource_destroy(r); + + done: + return; + + no_resource: + pw_log_error("can't find resouce %d", id); + pw_core_resource_error(client->core_resource, + resource->id, -EINVAL, "unknown resouce %d", id); + goto done; } static const struct pw_core_proxy_methods core_methods = { diff --git a/src/pipewire/global.c b/src/pipewire/global.c index 591dfa8c2..6fc441350 100644 --- a/src/pipewire/global.c +++ b/src/pipewire/global.c @@ -259,9 +259,9 @@ void pw_global_destroy(struct pw_global *global) { struct pw_core *core = global->core; + pw_log_debug("global %p: destroy %u", global, global->id); global_unregister(global); - pw_log_debug("global %p: destroy %u", global, global->id); pw_global_events_destroy(global); pw_map_remove(&core->globals, global->id); diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h index b31c7cba9..e98278a1d 100644 --- a/src/pipewire/interfaces.h +++ b/src/pipewire/interfaces.h @@ -172,11 +172,12 @@ struct pw_core_proxy_methods { uint32_t version, const struct spa_dict *props, uint32_t new_id); - /** - * Destroy an object id + * Destroy an resource * - * \param id the object id to destroy + * Destroy the server resource with the given proxy id. + * + * \param id the client proxy id to destroy */ void (*destroy) (void *object, uint32_t id); }; @@ -228,9 +229,9 @@ pw_core_proxy_create_object(struct pw_core_proxy *core, } static inline void -pw_core_proxy_destroy(struct pw_core_proxy *core, uint32_t id) +pw_core_proxy_destroy(struct pw_core_proxy *core, struct pw_proxy *proxy) { - pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, destroy, id); + pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, destroy, pw_proxy_get_id(proxy)); } #define PW_CORE_PROXY_EVENT_DONE 0 @@ -336,7 +337,8 @@ pw_core_proxy_add_listener(struct pw_core_proxy *core, * the access permissions on an object. */ #define PW_REGISTRY_PROXY_METHOD_BIND 0 -#define PW_REGISTRY_PROXY_METHOD_NUM 1 +#define PW_REGISTRY_PROXY_METHOD_DESTROY 1 +#define PW_REGISTRY_PROXY_METHOD_NUM 2 /** Registry methods */ struct pw_registry_proxy_methods { @@ -355,6 +357,15 @@ struct pw_registry_proxy_methods { * \param new_id the client proxy to use */ void (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id); + + /** + * Attempt to destroy a global object + * + * Try to destroy the global object. + * + * \param id the global id to destroy + */ + void (*destroy) (void *object, uint32_t id); }; /** Registry */ @@ -369,6 +380,13 @@ pw_registry_proxy_bind(struct pw_registry_proxy *registry, return p; } +static inline void +pw_registry_proxy_destroy(struct pw_registry_proxy *registry, uint32_t id) +{ + struct pw_proxy *reg = (struct pw_proxy*)registry; + pw_proxy_do(reg, struct pw_registry_proxy_methods, destroy, id); +} + #define PW_REGISTRY_PROXY_EVENT_GLOBAL 0 #define PW_REGISTRY_PROXY_EVENT_GLOBAL_REMOVE 1 #define PW_REGISTRY_PROXY_EVENT_NUM 2 diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index cc01cc861..874b187d9 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -1270,8 +1270,9 @@ static void do_node_init(struct pw_proxy *proxy) static void node_destroy(void *data) { struct node_data *d = data; + struct pw_remote *remote = d->remote; pw_log_debug("%p: destroy", d); - pw_client_node_proxy_destroy(d->node_proxy); + pw_core_proxy_destroy(remote->core_proxy, (struct pw_proxy *)d->node_proxy); pw_proxy_destroy((struct pw_proxy *)d->node_proxy); } diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index 3f28ebcff..775d0be9d 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -992,7 +992,7 @@ static bool do_destroy(struct data *data, const char *cmd, char *args, char **er asprintf(error, "%s: unknown global %d", cmd, id); return false; } - pw_core_proxy_destroy(rd->core_proxy, id); + pw_registry_proxy_destroy(rd->registry_proxy, id); return true; }