mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Add link introspection
This commit is contained in:
		
							parent
							
								
									b969623ec8
								
							
						
					
					
						commit
						e6f45a7686
					
				
					 8 changed files with 156 additions and 39 deletions
				
			
		| 
						 | 
				
			
			@ -255,6 +255,46 @@ client_dispatch_func (void             *object,
 | 
			
		|||
  return SPA_RESULT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SpaResult
 | 
			
		||||
link_dispatch_func (void             *object,
 | 
			
		||||
                    PinosMessageType  type,
 | 
			
		||||
                    void             *message,
 | 
			
		||||
                    void             *data)
 | 
			
		||||
{
 | 
			
		||||
  PinosContextImpl *impl = data;
 | 
			
		||||
  PinosContext *this = &impl->this;
 | 
			
		||||
  PinosProxy *proxy = object;
 | 
			
		||||
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case PINOS_MESSAGE_LINK_INFO:
 | 
			
		||||
    {
 | 
			
		||||
      PinosMessageLinkInfo *m = message;
 | 
			
		||||
      PinosSubscriptionEvent event;
 | 
			
		||||
 | 
			
		||||
      pinos_log_debug ("got link info %d", type);
 | 
			
		||||
      if (proxy->user_data == NULL)
 | 
			
		||||
        event = PINOS_SUBSCRIPTION_EVENT_NEW;
 | 
			
		||||
      else
 | 
			
		||||
        event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
 | 
			
		||||
 | 
			
		||||
      proxy->user_data = pinos_link_info_update (proxy->user_data, m->info);
 | 
			
		||||
 | 
			
		||||
      if (impl->subscribe_func) {
 | 
			
		||||
        impl->subscribe_func (this,
 | 
			
		||||
                              event,
 | 
			
		||||
                              proxy->type,
 | 
			
		||||
                              proxy->id,
 | 
			
		||||
                              impl->subscribe_data);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
      pinos_log_warn ("unhandled message %d", type);
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  return SPA_RESULT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SpaResult
 | 
			
		||||
registry_dispatch_func (void             *object,
 | 
			
		||||
                        PinosMessageType  type,
 | 
			
		||||
| 
						 | 
				
			
			@ -291,6 +331,11 @@ registry_dispatch_func (void             *object,
 | 
			
		|||
        proxy->dispatch_func = client_dispatch_func;
 | 
			
		||||
        proxy->dispatch_data = impl;
 | 
			
		||||
      } else if (!strcmp (ng->type, PINOS_LINK_URI)) {
 | 
			
		||||
        proxy = pinos_proxy_new (this,
 | 
			
		||||
                                 SPA_ID_INVALID,
 | 
			
		||||
                                 this->uri.link);
 | 
			
		||||
        proxy->dispatch_func = link_dispatch_func;
 | 
			
		||||
        proxy->dispatch_data = impl;
 | 
			
		||||
      }
 | 
			
		||||
      if (proxy) {
 | 
			
		||||
        PinosMessageBind m;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -277,3 +277,39 @@ pinos_client_info_free   (PinosClientInfo       *info)
 | 
			
		|||
    pinos_spa_dict_destroy (info->props);
 | 
			
		||||
  free (info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PinosLinkInfo *
 | 
			
		||||
pinos_link_info_update (PinosLinkInfo       *info,
 | 
			
		||||
                        const PinosLinkInfo *update)
 | 
			
		||||
{
 | 
			
		||||
  uint64_t change_mask;
 | 
			
		||||
 | 
			
		||||
  if (update == NULL)
 | 
			
		||||
    return info;
 | 
			
		||||
 | 
			
		||||
  if (info == NULL) {
 | 
			
		||||
    info = calloc (1, sizeof (PinosLinkInfo));
 | 
			
		||||
    change_mask = ~0;
 | 
			
		||||
  } else {
 | 
			
		||||
    change_mask = info->change_mask | update->change_mask;
 | 
			
		||||
  }
 | 
			
		||||
  info->id = update->id;
 | 
			
		||||
  info->change_mask = change_mask;
 | 
			
		||||
 | 
			
		||||
  if (update->change_mask & (1 << 0))
 | 
			
		||||
    info->output_node_id = update->output_node_id;
 | 
			
		||||
  if (update->change_mask & (1 << 1))
 | 
			
		||||
    info->output_port_id = update->output_port_id;
 | 
			
		||||
  if (update->change_mask & (1 << 2))
 | 
			
		||||
    info->input_node_id = update->input_node_id;
 | 
			
		||||
  if (update->change_mask & (1 << 3))
 | 
			
		||||
    info->input_port_id = update->input_port_id;
 | 
			
		||||
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
pinos_link_info_free (PinosLinkInfo       *info)
 | 
			
		||||
{
 | 
			
		||||
  free (info);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -301,6 +301,10 @@ struct _PinosLinkInfo {
 | 
			
		|||
  uint32_t input_port_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PinosLinkInfo *    pinos_link_info_update (PinosLinkInfo       *info,
 | 
			
		||||
                                           const PinosLinkInfo *update);
 | 
			
		||||
void               pinos_link_info_free   (PinosLinkInfo       *info);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PinosLinkInfoCallback:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -606,37 +606,6 @@ stream_dispatch_func (void             *object,
 | 
			
		|||
  PinosStreamImpl *impl = SPA_CONTAINER_OF (stream, PinosStreamImpl, this);
 | 
			
		||||
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case PINOS_MESSAGE_SYNC:
 | 
			
		||||
    case PINOS_MESSAGE_GET_REGISTRY:
 | 
			
		||||
    case PINOS_MESSAGE_BIND:
 | 
			
		||||
    case PINOS_MESSAGE_DESTROY:
 | 
			
		||||
    case PINOS_MESSAGE_REMOVE_ID:
 | 
			
		||||
    case PINOS_MESSAGE_CREATE_NODE:
 | 
			
		||||
    case PINOS_MESSAGE_CREATE_CLIENT_NODE:
 | 
			
		||||
    case PINOS_MESSAGE_NODE_UPDATE:
 | 
			
		||||
    case PINOS_MESSAGE_PORT_UPDATE:
 | 
			
		||||
    case PINOS_MESSAGE_PORT_STATUS_CHANGE:
 | 
			
		||||
    case PINOS_MESSAGE_NODE_STATE_CHANGE:
 | 
			
		||||
    case PINOS_MESSAGE_CORE_INFO:
 | 
			
		||||
    case PINOS_MESSAGE_MODULE_INFO:
 | 
			
		||||
    case PINOS_MESSAGE_NODE_INFO:
 | 
			
		||||
    case PINOS_MESSAGE_CLIENT_INFO:
 | 
			
		||||
    case PINOS_MESSAGE_LINK_INFO:
 | 
			
		||||
      pinos_log_warn ("got unexpected message %d", type);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_NOTIFY_DONE:
 | 
			
		||||
      pinos_log_warn ("notify done %d", type);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_NOTIFY_GLOBAL:
 | 
			
		||||
      pinos_log_warn ("notify global %d", type);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE:
 | 
			
		||||
      pinos_log_warn ("notify global %d", type);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PINOS_MESSAGE_CREATE_NODE_DONE:
 | 
			
		||||
      pinos_log_warn ("create node done %d", type);
 | 
			
		||||
      break;
 | 
			
		||||
| 
						 | 
				
			
			@ -838,6 +807,7 @@ stream_dispatch_func (void             *object,
 | 
			
		|||
      pinos_log_debug ("transport update %d %p", impl->rtfd, impl->trans);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
    case PINOS_MESSAGE_INVALID:
 | 
			
		||||
      pinos_log_warn ("unhandled message %d", type);
 | 
			
		||||
      break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,17 +82,33 @@ typedef struct {
 | 
			
		|||
} PinosProtocolNativeClient;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
client_destroy (PinosProtocolNativeClient *this)
 | 
			
		||||
sync_destroy (void      *object,
 | 
			
		||||
              void      *data,
 | 
			
		||||
              SpaResult  res,
 | 
			
		||||
              uint32_t   id)
 | 
			
		||||
{
 | 
			
		||||
  pinos_client_destroy (this->client);
 | 
			
		||||
  spa_list_remove (&this->link);
 | 
			
		||||
  pinos_loop_destroy_source (this->impl->core->main_loop->loop,
 | 
			
		||||
                             this->source);
 | 
			
		||||
  PinosProtocolNativeClient *this = object;
 | 
			
		||||
 | 
			
		||||
  pinos_connection_destroy (this->connection);
 | 
			
		||||
  close (this->fd);
 | 
			
		||||
  free (this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
client_destroy (PinosProtocolNativeClient *this)
 | 
			
		||||
{
 | 
			
		||||
  pinos_loop_destroy_source (this->impl->core->main_loop->loop,
 | 
			
		||||
                             this->source);
 | 
			
		||||
  pinos_client_destroy (this->client);
 | 
			
		||||
  spa_list_remove (&this->link);
 | 
			
		||||
 | 
			
		||||
  pinos_main_loop_defer (this->impl->core->main_loop,
 | 
			
		||||
                         this,
 | 
			
		||||
                         SPA_RESULT_WAIT_SYNC,
 | 
			
		||||
                         sync_destroy,
 | 
			
		||||
                         this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SpaResult
 | 
			
		||||
client_send_func (void             *object,
 | 
			
		||||
                  uint32_t          id,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -277,6 +277,8 @@ pinos_core_add_global (PinosCore           *core,
 | 
			
		|||
                       PinosBindFunc        bind)
 | 
			
		||||
{
 | 
			
		||||
  PinosGlobal *global;
 | 
			
		||||
  PinosResource *registry;
 | 
			
		||||
  PinosMessageNotifyGlobal ng;
 | 
			
		||||
 | 
			
		||||
  global = calloc (1, sizeof (PinosGlobal));
 | 
			
		||||
  global->core = core;
 | 
			
		||||
| 
						 | 
				
			
			@ -294,6 +296,14 @@ pinos_core_add_global (PinosCore           *core,
 | 
			
		|||
 | 
			
		||||
  pinos_log_debug ("global %p: new %u", global, global->id);
 | 
			
		||||
 | 
			
		||||
  ng.id = global->id;
 | 
			
		||||
  ng.type = spa_id_map_get_uri (core->uri.map, global->type);
 | 
			
		||||
  spa_list_for_each (registry, &core->registry_resource_list, link) {
 | 
			
		||||
    pinos_resource_send_message (registry,
 | 
			
		||||
                                 PINOS_MESSAGE_NOTIFY_GLOBAL,
 | 
			
		||||
                                 &ng,
 | 
			
		||||
                                 true);
 | 
			
		||||
  }
 | 
			
		||||
  return global;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -313,6 +323,8 @@ void
 | 
			
		|||
pinos_global_destroy (PinosGlobal *global)
 | 
			
		||||
{
 | 
			
		||||
  PinosCore *core = global->core;
 | 
			
		||||
  PinosResource *registry;
 | 
			
		||||
  PinosMessageNotifyGlobalRemove ng;
 | 
			
		||||
 | 
			
		||||
  pinos_log_debug ("global %p: destroy", global);
 | 
			
		||||
  pinos_signal_emit (&global->destroy_signal, global);
 | 
			
		||||
| 
						 | 
				
			
			@ -322,6 +334,14 @@ pinos_global_destroy (PinosGlobal *global)
 | 
			
		|||
  spa_list_remove (&global->link);
 | 
			
		||||
  pinos_signal_emit (&core->global_removed, core, global);
 | 
			
		||||
 | 
			
		||||
  ng.id = global->id;
 | 
			
		||||
  spa_list_for_each (registry, &core->registry_resource_list, link) {
 | 
			
		||||
    pinos_resource_send_message (registry,
 | 
			
		||||
                                 PINOS_MESSAGE_NOTIFY_GLOBAL_REMOVE,
 | 
			
		||||
                                 &ng,
 | 
			
		||||
                                 true);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pinos_main_loop_defer (core->main_loop,
 | 
			
		||||
                         global,
 | 
			
		||||
                         SPA_RESULT_WAIT_SYNC,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -681,24 +681,48 @@ link_dispatch_func (void             *object,
 | 
			
		|||
  return SPA_RESULT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
link_unbind_func (void *data)
 | 
			
		||||
{
 | 
			
		||||
  PinosResource *resource = data;
 | 
			
		||||
  spa_list_remove (&resource->link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
link_bind_func (PinosGlobal *global,
 | 
			
		||||
                PinosClient *client,
 | 
			
		||||
                uint32_t     version,
 | 
			
		||||
                uint32_t     id)
 | 
			
		||||
{
 | 
			
		||||
  PinosLink *this = global->object;
 | 
			
		||||
  PinosResource *resource;
 | 
			
		||||
  PinosMessageLinkInfo m;
 | 
			
		||||
  PinosLinkInfo info;
 | 
			
		||||
 | 
			
		||||
  resource = pinos_resource_new (client,
 | 
			
		||||
                                 id,
 | 
			
		||||
                                 global->core->uri.link,
 | 
			
		||||
                                 global->object,
 | 
			
		||||
                                 NULL);
 | 
			
		||||
                                 link_unbind_func);
 | 
			
		||||
 | 
			
		||||
  resource->dispatch_func = link_dispatch_func;
 | 
			
		||||
  resource->dispatch_data = client;
 | 
			
		||||
  resource->dispatch_data = global;
 | 
			
		||||
 | 
			
		||||
  pinos_log_debug ("link %p: bound to %d", global->object, resource->id);
 | 
			
		||||
 | 
			
		||||
  spa_list_insert (this->resource_list.prev, &resource->link);
 | 
			
		||||
 | 
			
		||||
  m.info = &info;
 | 
			
		||||
  info.id = resource->id;
 | 
			
		||||
  info.change_mask = ~0;
 | 
			
		||||
  info.output_node_id = this->output ? this->output->node->global->id : -1;
 | 
			
		||||
  info.output_port_id = this->output ? this->output->port_id : -1;
 | 
			
		||||
  info.input_node_id = this->input ? this->input->node->global->id : -1;
 | 
			
		||||
  info.input_port_id = this->input ? this->input->port_id : -1;
 | 
			
		||||
  pinos_resource_send_message (resource,
 | 
			
		||||
                               PINOS_MESSAGE_LINK_INFO,
 | 
			
		||||
                               &m,
 | 
			
		||||
                               true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PinosLink *
 | 
			
		||||
| 
						 | 
				
			
			@ -722,6 +746,7 @@ pinos_link_new (PinosCore       *core,
 | 
			
		|||
  this->input = input;
 | 
			
		||||
  this->output = output;
 | 
			
		||||
 | 
			
		||||
  spa_list_init (&this->resource_list);
 | 
			
		||||
  pinos_signal_init (&this->destroy_signal);
 | 
			
		||||
 | 
			
		||||
  impl->format_filter = format_filter;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,9 +52,10 @@ struct _PinosLink {
 | 
			
		|||
  PINOS_SIGNAL (destroy_signal, (PinosListener *,
 | 
			
		||||
                                 PinosLink *));
 | 
			
		||||
 | 
			
		||||
  SpaList resource_list;
 | 
			
		||||
 | 
			
		||||
  PinosPort    *output;
 | 
			
		||||
  SpaList       output_link;
 | 
			
		||||
 | 
			
		||||
  PinosPort    *input;
 | 
			
		||||
  SpaList       input_link;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue