diff --git a/lib/wp/endpoint.c b/lib/wp/endpoint.c index bb30d41cf5bb8605c9432635dc04b80c2551fdb8..a2da28e74c87d7533b4a53fb4fc082a8e964ebcd 100644 --- a/lib/wp/endpoint.c +++ b/lib/wp/endpoint.c @@ -88,6 +88,7 @@ wp_endpoint_emit_streams_changed (WpObjectManager *streams_om, WpEndpoint * self) { g_signal_emit (self, signals[SIGNAL_STREAMS_CHANGED], 0); + wp_proxy_set_feature_ready (WP_PROXY (self), WP_ENDPOINT_FEATURE_STREAMS); } static void @@ -97,15 +98,15 @@ wp_endpoint_ensure_feature_streams (WpEndpoint * self, guint32 bound_id) WpProxyFeatures ft = wp_proxy_get_features (WP_PROXY (self)); if (priv->ft_streams_requested && !priv->streams_om && - (ft & WP_PROXY_FEATURE_BOUND)) + (ft & WP_PROXY_FEATURES_STANDARD) == WP_PROXY_FEATURES_STANDARD) { g_autoptr (WpCore) core = wp_proxy_get_core (WP_PROXY (self)); if (!bound_id) bound_id = wp_proxy_get_bound_id (WP_PROXY (self)); - wp_debug_object (self, "enabling WP_ENDPOINT_FEATURE_STREAMS, bound_id:%u", - bound_id); + wp_debug_object (self, "enabling WP_ENDPOINT_FEATURE_STREAMS, bound_id:%u, " + "n_streams:%u", bound_id, priv->info->n_streams); priv->streams_om = wp_object_manager_new (); /* proxy endpoint stream -> check for endpoint.id in global properties */ @@ -121,8 +122,18 @@ wp_endpoint_ensure_feature_streams (WpEndpoint * self, guint32 bound_id) wp_object_manager_request_proxy_features (priv->streams_om, WP_TYPE_ENDPOINT_STREAM, WP_PROXY_FEATURES_STANDARD); - g_signal_connect_object (priv->streams_om, "installed", - G_CALLBACK (wp_endpoint_on_streams_om_installed), self, 0); + /* endpoints, under normal circumstances, always have streams. + When we export (self is a WpImplEndpoint), we have to export first + the endpoint and afterwards the streams (so that the streams can be + associated with the endpoint's bound id), but then the issue is that + the "installed" signal gets fired here without any streams being ready + and we get an endpoint with 0 streams in the WpSession's endpoints + object manager... so, unless the endpoint really has no streams, + wait for them to be prepared by waiting for the "objects-changed" only */ + if (G_UNLIKELY (priv->info->n_streams == 0)) { + g_signal_connect_object (priv->streams_om, "installed", + G_CALLBACK (wp_endpoint_on_streams_om_installed), self, 0); + } g_signal_connect_object (priv->streams_om, "objects-changed", G_CALLBACK (wp_endpoint_emit_streams_changed), self, 0); @@ -237,6 +248,8 @@ endpoint_event_info (void *data, const struct pw_endpoint_info *info) if (info->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) g_object_notify (G_OBJECT (self), "properties"); + + wp_endpoint_ensure_feature_streams (self, 0); } static const struct pw_endpoint_events endpoint_events = { diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c index dd4b61173252ed8e6e8bb3a863a3c60ab92b342e..d9b61c8cac6dbd69f0c06851f7b7cfb3570f0a31 100644 --- a/lib/wp/session-item.c +++ b/lib/wp/session-item.c @@ -189,6 +189,7 @@ wp_session_item_default_activate_get_next_step (WpSessionItem * self, enum { EXPORT_STEP_ENDPOINT = WP_TRANSITION_STEP_CUSTOM_START, EXPORT_STEP_STREAMS, + EXPORT_STEP_ENDPOINT_FT_STREAMS, EXPORT_STEP_LINK, EXPORT_STEP_CONNECT_DESTROYED, }; @@ -224,10 +225,13 @@ wp_session_item_default_export_get_next_step (WpSessionItem * self, /* go to next step only when all impl proxies are augmented */ if (g_hash_table_size (priv->impl_streams) == wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (self))) - return WP_TRANSITION_STEP_NONE; + return EXPORT_STEP_ENDPOINT_FT_STREAMS; else return step; + case EXPORT_STEP_ENDPOINT_FT_STREAMS: + return WP_TRANSITION_STEP_NONE; + case EXPORT_STEP_LINK: g_return_val_if_fail (WP_IS_SI_LINK (self), WP_TRANSITION_STEP_ERROR); return EXPORT_STEP_CONNECT_DESTROYED; @@ -262,6 +266,9 @@ on_export_proxy_augmented (WpProxy * proxy, GAsyncResult * res, gpointer data) g_hash_table_insert (priv->impl_streams, si_stream, g_object_ref (proxy)); } + wp_debug_object (self, "export proxy " WP_OBJECT_FORMAT " augmented", + WP_OBJECT_ARGS (proxy)); + wp_transition_advance (transition); } @@ -308,7 +315,7 @@ wp_session_item_default_export_execute_step (WpSessionItem * self, priv->impl_endpoint = wp_impl_endpoint_new (core, WP_SI_ENDPOINT (self)); wp_proxy_augment (WP_PROXY (priv->impl_endpoint), - WP_ENDPOINT_FEATURES_STANDARD, NULL, + WP_PROXY_FEATURES_STANDARD, NULL, (GAsyncReadyCallback) on_export_proxy_augmented, transition); break; @@ -336,6 +343,16 @@ wp_session_item_default_export_execute_step (WpSessionItem * self, } break; } + case EXPORT_STEP_ENDPOINT_FT_STREAMS: + /* add feature streams only after the streams are exported, otherwise + the endpoint will never be augmented in the first place (because it + internally waits for the streams to be ready) */ + wp_proxy_augment (WP_PROXY (priv->impl_endpoint), + WP_ENDPOINT_FEATURE_STREAMS, NULL, + (GAsyncReadyCallback) on_export_proxy_augmented, + transition); + break; + case EXPORT_STEP_LINK: priv->impl_link = wp_impl_endpoint_link_new (core, WP_SI_LINK (self));