diff --git a/pipewire/client/stream.c b/pipewire/client/stream.c index 1a54b5122..e30c0b261 100644 --- a/pipewire/client/stream.c +++ b/pipewire/client/stream.c @@ -647,6 +647,8 @@ client_node_set_format(void *object, struct pw_stream *stream = proxy->object; struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); + pw_log_debug("stream %p: format changed %d", stream, seq); + if (impl->format) free(impl->format); impl->format = format ? spa_format_copy(format) : NULL; @@ -942,6 +944,8 @@ pw_stream_finish_format(struct pw_stream *stream, { struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); + pw_log_debug("stream %p: finish format %d %d", stream, res, impl->pending_seq); + set_params(stream, n_params, params); if (SPA_RESULT_IS_OK(res)) { diff --git a/pipewire/gst/gstpipewiredeviceprovider.c b/pipewire/gst/gstpipewiredeviceprovider.c index 924f161a3..da8b5ac1e 100644 --- a/pipewire/gst/gstpipewiredeviceprovider.c +++ b/pipewire/gst/gstpipewiredeviceprovider.c @@ -220,7 +220,8 @@ new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info) gst_caps_append (caps, c1); } } else { - type = GST_PIPEWIRE_DEVICE_TYPE_UNKNOWN; + gst_caps_unref(caps); + return NULL; } props = gst_structure_new_empty ("pipewire-proplist"); @@ -323,7 +324,9 @@ list_node_info_cb (struct pw_context *c, { InfoData *data = user_data; if (info) { - *data->devices = g_list_prepend (*data->devices, gst_object_ref_sink (new_node (data->self, info))); + GstDevice *dev = new_node (data->self, info); + if (dev) + *data->devices = g_list_prepend (*data->devices, gst_object_ref_sink (dev)); } else { data->end = TRUE; } diff --git a/pipewire/gst/gstpipewiresink.c b/pipewire/gst/gstpipewiresink.c index 08673c39b..1454b139d 100644 --- a/pipewire/gst/gstpipewiresink.c +++ b/pipewire/gst/gstpipewiresink.c @@ -648,7 +648,7 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) while (TRUE) { state = pwsink->stream->state; - if (state == PW_STREAM_STATE_CONFIGURE) + if (state == PW_STREAM_STATE_READY) break; if (state == PW_STREAM_STATE_ERROR) diff --git a/pipewire/modules/module-autolink.c b/pipewire/modules/module-autolink.c index 02746a2d7..2c6d8e742 100644 --- a/pipewire/modules/module-autolink.c +++ b/pipewire/modules/module-autolink.c @@ -46,6 +46,7 @@ struct node_info { struct pw_listener port_removed; struct pw_listener port_unlinked; struct pw_listener link_state_changed; + struct pw_listener link_destroy; }; static struct node_info *find_node_info(struct impl *impl, struct pw_node *node) @@ -66,6 +67,7 @@ static void node_info_free(struct node_info *info) pw_signal_remove(&info->port_added); pw_signal_remove(&info->port_removed); pw_signal_remove(&info->port_unlinked); + pw_signal_remove(&info->link_destroy); pw_signal_remove(&info->link_state_changed); free(info); } @@ -124,6 +126,21 @@ on_link_state_changed(struct pw_listener *listener, } } +static void +on_link_destroy(struct pw_listener *listener, struct pw_link *link) +{ + struct node_info *info = SPA_CONTAINER_OF(listener, struct node_info, link_destroy); + struct impl *impl = info->impl; + + pw_log_debug("module %p: link %p destroyed", impl, link); + pw_signal_remove(&info->port_unlinked); + pw_signal_remove(&info->link_state_changed); + pw_signal_remove(&info->link_destroy); + spa_list_init(&info->port_unlinked.link); + spa_list_init(&info->link_state_changed.link); + spa_list_init(&info->link_destroy.link); +} + static void try_link_port(struct pw_node *node, struct pw_port *port, struct node_info *info) { struct impl *impl = info->impl; @@ -168,6 +185,7 @@ static void try_link_port(struct pw_node *node, struct pw_port *port, struct nod pw_signal_add(&link->port_unlinked, &info->port_unlinked, on_link_port_unlinked); pw_signal_add(&link->state_changed, &info->link_state_changed, on_link_state_changed); + pw_signal_add(&link->destroy_signal, &info->link_destroy, on_link_destroy); pw_link_activate(link); diff --git a/pipewire/server/link.c b/pipewire/server/link.c index 3c90f7bbe..e4e7523ad 100644 --- a/pipewire/server/link.c +++ b/pipewire/server/link.c @@ -1127,9 +1127,11 @@ void pw_link_destroy(struct pw_link *link) input_remove(link, link->input); spa_list_remove(&link->input_link); + link->input = NULL; output_remove(link, link->output); spa_list_remove(&link->output_link); + link->output = NULL; pw_work_queue_destroy(impl->work); diff --git a/pipewire/server/node.c b/pipewire/server/node.c index 54d90bf56..cf08c64de 100644 --- a/pipewire/server/node.c +++ b/pipewire/server/node.c @@ -540,21 +540,27 @@ void pw_node_destroy(struct pw_node *node) pw_signal_emit(&node->destroy_signal, node); if (!impl->async_init) { + pw_loop_invoke(node->data_loop->loop, do_node_remove, 1, 0, NULL, true, node); + spa_list_remove(&node->link); pw_global_destroy(node->global); + node->global = NULL; } spa_list_for_each_safe(resource, tmp, &node->resource_list, link) pw_resource_destroy(resource); - pw_loop_invoke(node->data_loop->loop, do_node_remove, 1, 0, NULL, true, node); - pw_log_debug("node %p: destroy ports", node); - spa_list_for_each_safe(port, tmpp, &node->input_ports, link) + spa_list_for_each_safe(port, tmpp, &node->input_ports, link) { + pw_signal_emit(&node->port_removed, node, port); pw_port_destroy(port); + } - spa_list_for_each_safe(port, tmpp, &node->output_ports, link) + spa_list_for_each_safe(port, tmpp, &node->output_ports, link) { + pw_signal_emit(&node->port_removed, node, port); pw_port_destroy(port); + } + pw_log_debug("node %p: free", node); pw_signal_emit(&node->free_signal, node);