Improve introspection

Move introspectable info to the node and link.
Only enumerate the device formats once.
Change some field names.
Pass link format in introspection
This commit is contained in:
Wim Taymans 2017-06-02 10:40:43 +02:00
parent e48c361a66
commit dbe20c9934
14 changed files with 163 additions and 140 deletions

View file

@ -205,7 +205,7 @@ struct pw_node_info *pw_node_info_update(struct pw_node_info *info,
info->name = update->name ? strdup(update->name) : NULL; info->name = update->name ? strdup(update->name) : NULL;
} }
if (update->change_mask & (1 << 1)) if (update->change_mask & (1 << 1))
info->max_inputs = update->max_inputs; info->max_input_ports = update->max_input_ports;
if (update->change_mask & (1 << 2)) { if (update->change_mask & (1 << 2)) {
for (i = 0; i < info->n_input_formats; i++) for (i = 0; i < info->n_input_formats; i++)
free(info->input_formats[i]); free(info->input_formats[i]);
@ -223,7 +223,7 @@ struct pw_node_info *pw_node_info_update(struct pw_node_info *info,
} }
} }
if (update->change_mask & (1 << 3)) if (update->change_mask & (1 << 3))
info->max_outputs = update->max_outputs; info->max_output_ports = update->max_output_ports;
if (update->change_mask & (1 << 4)) { if (update->change_mask & (1 << 4)) {
for (i = 0; i < info->n_output_formats; i++) for (i = 0; i < info->n_output_formats; i++)
free(info->output_formats[i]); free(info->output_formats[i]);
@ -395,11 +395,17 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info,
info->input_node_id = update->input_node_id; info->input_node_id = update->input_node_id;
if (update->change_mask & (1 << 3)) if (update->change_mask & (1 << 3))
info->input_port_id = update->input_port_id; info->input_port_id = update->input_port_id;
if (update->change_mask & (1 << 4)) {
if (info->format)
free(info->format);
info->format = spa_format_copy(update->format);
}
return info; return info;
} }
void pw_link_info_free(struct pw_link_info *info) void pw_link_info_free(struct pw_link_info *info)
{ {
if (info->format)
free(info->format);
free(info); free(info);
} }

View file

@ -195,12 +195,12 @@ struct pw_node_info {
uint32_t id; /**< server side id of the node */ uint32_t id; /**< server side id of the node */
uint64_t change_mask; /**< bitfield of changed fields since last call */ uint64_t change_mask; /**< bitfield of changed fields since last call */
const char *name; /**< name the node, suitable for display */ const char *name; /**< name the node, suitable for display */
uint32_t max_inputs; /**< maximum number of inputs */ uint32_t max_input_ports; /**< maximum number of inputs */
uint32_t n_inputs; /**< number of inputs */ uint32_t n_input_ports; /**< number of inputs */
uint32_t n_input_formats; /**< number of input formats */ uint32_t n_input_formats; /**< number of input formats */
struct spa_format **input_formats; /**< array of input formats */ struct spa_format **input_formats; /**< array of input formats */
uint32_t max_outputs; /**< maximum number of outputs */ uint32_t max_output_ports; /**< maximum number of outputs */
uint32_t n_outputs; /**< number of outputs */ uint32_t n_output_ports; /**< number of outputs */
uint32_t n_output_formats; /**< number of output formats */ uint32_t n_output_formats; /**< number of output formats */
struct spa_format **output_formats; /**< array of output formats */ struct spa_format **output_formats; /**< array of output formats */
enum pw_node_state state; /**< the current state of the node */ enum pw_node_state state; /**< the current state of the node */
@ -242,6 +242,7 @@ struct pw_link_info {
uint32_t output_port_id; /**< output port id */ uint32_t output_port_id; /**< output port id */
uint32_t input_node_id; /**< server side input node id */ uint32_t input_node_id; /**< server side input node id */
uint32_t input_port_id; /**< input port id */ uint32_t input_port_id; /**< input port id */
struct spa_format *format; /**< format over link */
}; };
struct pw_link_info * struct pw_link_info *

View file

@ -402,8 +402,8 @@ static bool node_demarshal_info(void *object, void *data, size_t size)
SPA_POD_TYPE_INT, &info.id, SPA_POD_TYPE_INT, &info.id,
SPA_POD_TYPE_LONG, &info.change_mask, SPA_POD_TYPE_LONG, &info.change_mask,
SPA_POD_TYPE_STRING, &info.name, SPA_POD_TYPE_STRING, &info.name,
SPA_POD_TYPE_INT, &info.max_inputs, SPA_POD_TYPE_INT, &info.max_input_ports,
SPA_POD_TYPE_INT, &info.n_inputs, SPA_POD_TYPE_INT, &info.n_input_ports,
SPA_POD_TYPE_INT, &info.n_input_formats, 0)) SPA_POD_TYPE_INT, &info.n_input_formats, 0))
return false; return false;
@ -413,8 +413,8 @@ static bool node_demarshal_info(void *object, void *data, size_t size)
return false; return false;
if (!spa_pod_iter_get(&it, if (!spa_pod_iter_get(&it,
SPA_POD_TYPE_INT, &info.max_outputs, SPA_POD_TYPE_INT, &info.max_output_ports,
SPA_POD_TYPE_INT, &info.n_outputs, SPA_POD_TYPE_INT, &info.n_output_ports,
SPA_POD_TYPE_INT, &info.n_output_formats, 0)) SPA_POD_TYPE_INT, &info.n_output_formats, 0))
return false; return false;
@ -866,7 +866,7 @@ static bool link_demarshal_info(void *object, void *data, size_t size)
{ {
struct pw_proxy *proxy = object; struct pw_proxy *proxy = object;
struct spa_pod_iter it; struct spa_pod_iter it;
struct pw_link_info info; struct pw_link_info info = { 0, };
if (!spa_pod_iter_struct(&it, data, size) || if (!spa_pod_iter_struct(&it, data, size) ||
!spa_pod_iter_get(&it, !spa_pod_iter_get(&it,
@ -875,7 +875,8 @@ static bool link_demarshal_info(void *object, void *data, size_t size)
SPA_POD_TYPE_INT, &info.output_node_id, SPA_POD_TYPE_INT, &info.output_node_id,
SPA_POD_TYPE_INT, &info.output_port_id, SPA_POD_TYPE_INT, &info.output_port_id,
SPA_POD_TYPE_INT, &info.input_node_id, SPA_POD_TYPE_INT, &info.input_node_id,
SPA_POD_TYPE_INT, &info.input_port_id, 0)) SPA_POD_TYPE_INT, &info.input_port_id,
-SPA_POD_TYPE_OBJECT, &info.format, 0))
return false; return false;
((struct pw_link_events *) proxy->implementation)->info(proxy, &info); ((struct pw_link_events *) proxy->implementation)->info(proxy, &info);

View file

@ -481,7 +481,7 @@ static void handle_rtnode_event(struct pw_stream *stream, struct spa_event *even
if (SPA_EVENT_TYPE(event) == context->type.event_transport.HaveOutput) { if (SPA_EVENT_TYPE(event) == context->type.event_transport.HaveOutput) {
int i; int i;
for (i = 0; i < impl->trans->area->n_inputs; i++) { for (i = 0; i < impl->trans->area->n_input_ports; i++) {
struct spa_port_io *input = &impl->trans->inputs[i]; struct spa_port_io *input = &impl->trans->inputs[i];
pw_log_trace("stream %p: have output %d %d", stream, input->status, pw_log_trace("stream %p: have output %d %d", stream, input->status,
@ -496,7 +496,7 @@ static void handle_rtnode_event(struct pw_stream *stream, struct spa_event *even
} else if (SPA_EVENT_TYPE(event) == context->type.event_transport.NeedInput) { } else if (SPA_EVENT_TYPE(event) == context->type.event_transport.NeedInput) {
int i; int i;
for (i = 0; i < impl->trans->area->n_outputs; i++) { for (i = 0; i < impl->trans->area->n_output_ports; i++) {
struct spa_port_io *output = &impl->trans->outputs[i]; struct spa_port_io *output = &impl->trans->outputs[i];
if (output->buffer_id == SPA_ID_INVALID) if (output->buffer_id == SPA_ID_INVALID)

View file

@ -49,8 +49,8 @@ static size_t transport_area_get_size(struct pw_transport_area *area)
{ {
size_t size; size_t size;
size = sizeof(struct pw_transport_area); size = sizeof(struct pw_transport_area);
size += area->max_inputs * sizeof(struct spa_port_io); size += area->max_input_ports * sizeof(struct spa_port_io);
size += area->max_outputs * sizeof(struct spa_port_io); size += area->max_output_ports * sizeof(struct spa_port_io);
size += sizeof(struct spa_ringbuffer); size += sizeof(struct spa_ringbuffer);
size += INPUT_BUFFER_SIZE; size += INPUT_BUFFER_SIZE;
size += sizeof(struct spa_ringbuffer); size += sizeof(struct spa_ringbuffer);
@ -66,10 +66,10 @@ static void transport_setup_area(void *p, struct pw_transport *trans)
p = SPA_MEMBER(p, sizeof(struct pw_transport_area), struct spa_port_io); p = SPA_MEMBER(p, sizeof(struct pw_transport_area), struct spa_port_io);
trans->inputs = p; trans->inputs = p;
p = SPA_MEMBER(p, a->max_inputs * sizeof(struct spa_port_io), void); p = SPA_MEMBER(p, a->max_input_ports * sizeof(struct spa_port_io), void);
trans->outputs = p; trans->outputs = p;
p = SPA_MEMBER(p, a->max_outputs * sizeof(struct spa_port_io), void); p = SPA_MEMBER(p, a->max_output_ports * sizeof(struct spa_port_io), void);
trans->input_buffer = p; trans->input_buffer = p;
p = SPA_MEMBER(p, sizeof(struct spa_ringbuffer), void); p = SPA_MEMBER(p, sizeof(struct spa_ringbuffer), void);
@ -89,11 +89,11 @@ static void transport_reset_area(struct pw_transport *trans)
int i; int i;
struct pw_transport_area *a = trans->area; struct pw_transport_area *a = trans->area;
for (i = 0; i < a->max_inputs; i++) { for (i = 0; i < a->max_input_ports; i++) {
trans->inputs[i].status = SPA_RESULT_OK; trans->inputs[i].status = SPA_RESULT_OK;
trans->inputs[i].buffer_id = SPA_ID_INVALID; trans->inputs[i].buffer_id = SPA_ID_INVALID;
} }
for (i = 0; i < a->max_outputs; i++) { for (i = 0; i < a->max_output_ports; i++) {
trans->outputs[i].status = SPA_RESULT_OK; trans->outputs[i].status = SPA_RESULT_OK;
trans->outputs[i].buffer_id = SPA_ID_INVALID; trans->outputs[i].buffer_id = SPA_ID_INVALID;
} }
@ -102,21 +102,21 @@ static void transport_reset_area(struct pw_transport *trans)
} }
/** Create a new transport /** Create a new transport
* \param max_inputs maximum number of inputs * \param max_input_ports maximum number of input_ports
* \param max_outputs maximum number of outputs * \param max_output_ports maximum number of output_ports
* \return a newly allocated \ref pw_transport * \return a newly allocated \ref pw_transport
* \memberof pw_transport * \memberof pw_transport
*/ */
struct pw_transport *pw_transport_new(uint32_t max_inputs, uint32_t max_outputs) struct pw_transport *pw_transport_new(uint32_t max_input_ports, uint32_t max_output_ports)
{ {
struct transport *impl; struct transport *impl;
struct pw_transport *trans; struct pw_transport *trans;
struct pw_transport_area area; struct pw_transport_area area;
area.max_inputs = max_inputs; area.max_input_ports = max_input_ports;
area.n_inputs = 0; area.n_input_ports = 0;
area.max_outputs = max_outputs; area.max_output_ports = max_output_ports;
area.n_outputs = 0; area.n_output_ports = 0;
impl = calloc(1, sizeof(struct transport)); impl = calloc(1, sizeof(struct transport));
if (impl == NULL) if (impl == NULL)

View file

@ -41,10 +41,10 @@ struct pw_transport_info {
/** Shared structure between client and server \memberof pw_transport */ /** Shared structure between client and server \memberof pw_transport */
struct pw_transport_area { struct pw_transport_area {
uint32_t max_inputs; /**< max inputs of the node */ uint32_t max_input_ports; /**< max input ports of the node */
uint32_t n_inputs; /**< number of inputs of the node */ uint32_t n_input_ports; /**< number of input ports of the node */
uint32_t max_outputs; /**< max outputs of the node */ uint32_t max_output_ports; /**< max output ports of the node */
uint32_t n_outputs; /**< number of outputs of the node */ uint32_t n_output_ports; /**< number of output ports of the node */
}; };
/** \class pw_transport /** \class pw_transport
@ -69,7 +69,7 @@ struct pw_transport {
}; };
struct pw_transport * struct pw_transport *
pw_transport_new(uint32_t max_inputs, uint32_t max_outputs); pw_transport_new(uint32_t max_input_ports, uint32_t max_output_ports);
struct pw_transport * struct pw_transport *
pw_transport_new_from_info(struct pw_transport_info *info); pw_transport_new_from_info(struct pw_transport_info *info);

View file

@ -203,7 +203,7 @@ new_node (const struct pw_node_info *info)
int i; int i;
caps = gst_caps_new_empty (); caps = gst_caps_new_empty ();
if (info->max_inputs > 0 && info->max_outputs == 0) { if (info->max_input_ports > 0 && info->max_output_ports == 0) {
type = GST_PIPEWIRE_DEVICE_TYPE_SINK; type = GST_PIPEWIRE_DEVICE_TYPE_SINK;
for (i = 0; i < info->n_input_formats; i++) { for (i = 0; i < info->n_input_formats; i++) {
@ -212,7 +212,7 @@ new_node (const struct pw_node_info *info)
gst_caps_append (caps, c1); gst_caps_append (caps, c1);
} }
} }
else if (info->max_outputs > 0 && info->max_inputs == 0) { else if (info->max_output_ports > 0 && info->max_input_ports == 0) {
type = GST_PIPEWIRE_DEVICE_TYPE_SOURCE; type = GST_PIPEWIRE_DEVICE_TYPE_SOURCE;
for (i = 0; i < info->n_output_formats; i++) { for (i = 0; i < info->n_output_formats; i++) {
GstCaps *c1 = gst_caps_from_format (info->output_formats[i]); GstCaps *c1 = gst_caps_from_format (info->output_formats[i]);

View file

@ -1032,9 +1032,9 @@ static void on_initialized(struct pw_listener *listener, struct pw_node *node)
if (this->resource == NULL) if (this->resource == NULL)
return; return;
impl->transport = pw_transport_new(node->max_input_ports, node->max_output_ports); impl->transport = pw_transport_new(node->info.max_input_ports, node->info.max_output_ports);
impl->transport->area->n_inputs = node->n_input_ports; impl->transport->area->n_input_ports = node->info.n_input_ports;
impl->transport->area->n_outputs = node->n_output_ports; impl->transport->area->n_output_ports = node->info.n_output_ports;
pw_transport_get_info(impl->transport, &info); pw_transport_get_info(impl->transport, &info);
pw_client_node_notify_transport(this->resource, info.memfd, info.offset, info.size); pw_client_node_notify_transport(this->resource, info.memfd, info.offset, info.size);

View file

@ -831,7 +831,6 @@ link_bind_func(struct pw_global *global, struct pw_client *client, uint32_t vers
struct pw_link *this = global->object; struct pw_link *this = global->object;
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
struct pw_resource *resource; struct pw_resource *resource;
struct pw_link_info info;
resource = pw_resource_new(client, id, global->type, global->object, link_unbind_func); resource = pw_resource_new(client, id, global->type, global->object, link_unbind_func);
if (resource == NULL) if (resource == NULL)
@ -843,14 +842,8 @@ link_bind_func(struct pw_global *global, struct pw_client *client, uint32_t vers
spa_list_insert(this->resource_list.prev, &resource->link); spa_list_insert(this->resource_list.prev, &resource->link);
info.id = global->id; this->info.change_mask = ~0;
info.change_mask = ~0; pw_link_notify_info(resource, &this->info);
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;
pw_link_notify_info(resource, &info);
return SPA_RESULT_OK; return SPA_RESULT_OK;
@ -925,6 +918,14 @@ struct pw_link *pw_link_new(struct pw_core *core,
spa_list_insert(core->link_list.prev, &this->link); spa_list_insert(core->link_list.prev, &this->link);
pw_core_add_global(core, NULL, core->type.link, 0, this, link_bind_func, &this->global); pw_core_add_global(core, NULL, core->type.link, 0, this, link_bind_func, &this->global);
this->info.id = this->global->id;
this->info.output_node_id = output ? output->node->global->id : -1;
this->info.output_port_id = output ? output->port_id : -1;
this->info.input_node_id = input ? input->node->global->id : -1;
this->info.input_port_id = input ? input->port_id : -1;
this->info.format = NULL;
return this; return this;
} }

View file

@ -37,32 +37,38 @@ extern "C" {
* PipeWire link interface. * PipeWire link interface.
*/ */
struct pw_link { struct pw_link {
struct pw_core *core; struct pw_core *core; /**< core object */
struct spa_list link; struct spa_list link; /**< link in core link_list */
struct pw_global *global; struct pw_global *global; /**< global for this link */
struct pw_properties *properties; struct pw_properties *properties; /**< extra link properties */
enum pw_link_state state; struct pw_link_info info; /**< introspectable link info */
char *error;
enum pw_link_state state; /**< link state */
char *error; /**< error message when state error */
/** Emited when the link state changed */
PW_SIGNAL(state_changed, (struct pw_listener *listener, PW_SIGNAL(state_changed, (struct pw_listener *listener,
struct pw_link *link, struct pw_link *link,
enum pw_link_state old, enum pw_link_state state)); enum pw_link_state old, enum pw_link_state state));
/** Emited when the link is destroyed */
PW_SIGNAL(destroy_signal, (struct pw_listener *, struct pw_link *)); PW_SIGNAL(destroy_signal, (struct pw_listener *, struct pw_link *));
/** Emited when the object is freed */
PW_SIGNAL(free_signal, (struct pw_listener *, struct pw_link *)); PW_SIGNAL(free_signal, (struct pw_listener *, struct pw_link *));
struct spa_list resource_list; struct spa_list resource_list; /**< list of bound resources */
struct pw_port *output; struct pw_port *output; /**< output port */
struct spa_list output_link; struct spa_list output_link; /**< link in output port links */
struct pw_port *input; struct pw_port *input; /**< input port */
struct spa_list input_link; struct spa_list input_link; /**< link in input port links */
/** Emited when the port is unlinked */
PW_SIGNAL(port_unlinked, (struct pw_listener *listener, PW_SIGNAL(port_unlinked, (struct pw_listener *listener,
struct pw_link *link, struct pw_port *port)); struct pw_link *link, struct pw_port *port));
struct { struct {
uint32_t in_ready; // uint32_t in_ready;
struct pw_port *input; struct pw_port *input;
struct pw_port *output; struct pw_port *output;
struct spa_list input_link; struct spa_list input_link;

View file

@ -57,10 +57,10 @@ static void update_port_ids(struct pw_node *node)
spa_node_get_n_ports(node->node, spa_node_get_n_ports(node->node,
&n_input_ports, &max_input_ports, &n_output_ports, &max_output_ports); &n_input_ports, &max_input_ports, &n_output_ports, &max_output_ports);
node->n_input_ports = n_input_ports; node->info.n_input_ports = n_input_ports;
node->max_input_ports = max_input_ports; node->info.max_input_ports = max_input_ports;
node->n_output_ports = n_output_ports; node->info.n_output_ports = n_output_ports;
node->max_output_ports = max_output_ports; node->info.max_output_ports = max_output_ports;
node->input_port_map = calloc(max_input_ports, sizeof(struct pw_port *)); node->input_port_map = calloc(max_input_ports, sizeof(struct pw_port *));
node->output_port_map = calloc(max_output_ports, sizeof(struct pw_port *)); node->output_port_map = calloc(max_output_ports, sizeof(struct pw_port *));
@ -401,13 +401,68 @@ static void node_unbind_func(void *data)
spa_list_remove(&resource->link); spa_list_remove(&resource->link);
} }
static void
update_info(struct pw_node *this)
{
this->info.id = this->global->id;
this->info.name = this->name;
this->info.input_formats = NULL;
for (this->info.n_input_formats = 0;; this->info.n_input_formats++) {
struct spa_format *fmt;
if (spa_node_port_enum_formats(this->node,
SPA_DIRECTION_INPUT,
0, &fmt, NULL, this->info.n_input_formats) < 0)
break;
this->info.input_formats =
realloc(this->info.input_formats,
sizeof(struct spa_format *) * (this->info.n_input_formats + 1));
this->info.input_formats[this->info.n_input_formats] = spa_format_copy(fmt);
}
this->info.output_formats = NULL;
for (this->info.n_output_formats = 0;; this->info.n_output_formats++) {
struct spa_format *fmt;
if (spa_node_port_enum_formats(this->node,
SPA_DIRECTION_OUTPUT,
0, &fmt, NULL, this->info.n_output_formats) < 0)
break;
this->info.output_formats =
realloc(this->info.output_formats,
sizeof(struct spa_format *) * (this->info.n_output_formats + 1));
this->info.output_formats[this->info.n_output_formats] = spa_format_copy(fmt);
}
this->info.state = this->state;
this->info.error = this->error;
this->info.props = this->properties ? &this->properties->dict : NULL;
}
static void
clear_info(struct pw_node *this)
{
int i;
if (this->info.input_formats) {
for (i = 0; i < this->info.n_input_formats; i++)
free(this->info.input_formats[i]);
free(this->info.input_formats);
}
if (this->info.output_formats) {
for (i = 0; i < this->info.n_output_formats; i++)
free(this->info.output_formats[i]);
free(this->info.output_formats);
}
}
static int static int
node_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id) node_bind_func(struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id)
{ {
struct pw_node *this = global->object; struct pw_node *this = global->object;
struct pw_resource *resource; struct pw_resource *resource;
struct pw_node_info info;
int i;
resource = pw_resource_new(client, id, global->type, global->object, node_unbind_func); resource = pw_resource_new(client, id, global->type, global->object, node_unbind_func);
if (resource == NULL) if (resource == NULL)
@ -417,58 +472,8 @@ node_bind_func(struct pw_global *global, struct pw_client *client, uint32_t vers
spa_list_insert(this->resource_list.prev, &resource->link); spa_list_insert(this->resource_list.prev, &resource->link);
info.id = global->id; this->info.change_mask = ~0;
info.change_mask = ~0; pw_node_notify_info(resource, &this->info);
info.name = this->name;
info.max_inputs = this->max_input_ports;
info.n_inputs = this->n_input_ports;
info.input_formats = NULL;
for (info.n_input_formats = 0;; info.n_input_formats++) {
struct spa_format *fmt;
if (spa_node_port_enum_formats(this->node,
SPA_DIRECTION_INPUT,
0, &fmt, NULL, info.n_input_formats) < 0)
break;
info.input_formats =
realloc(info.input_formats,
sizeof(struct spa_format *) * (info.n_input_formats + 1));
info.input_formats[info.n_input_formats] = spa_format_copy(fmt);
}
info.max_outputs = this->max_output_ports;
info.n_outputs = this->n_output_ports;
info.output_formats = NULL;
for (info.n_output_formats = 0;; info.n_output_formats++) {
struct spa_format *fmt;
if (spa_node_port_enum_formats(this->node,
SPA_DIRECTION_OUTPUT,
0, &fmt, NULL, info.n_output_formats) < 0)
break;
info.output_formats =
realloc(info.output_formats,
sizeof(struct spa_format *) * (info.n_output_formats + 1));
info.output_formats[info.n_output_formats] = spa_format_copy(fmt);
}
info.state = this->state;
info.error = this->error;
info.props = this->properties ? &this->properties->dict : NULL;
pw_node_notify_info(resource, &info);
if (info.input_formats) {
for (i = 0; i < info.n_input_formats; i++)
free(info.input_formats[i]);
free(info.input_formats);
}
if (info.output_formats) {
for (i = 0; i < info.n_output_formats; i++)
free(info.output_formats[i]);
free(info.output_formats);
}
return SPA_RESULT_OK; return SPA_RESULT_OK;
@ -492,6 +497,8 @@ static void init_complete(struct pw_node *this)
this->owner, this->owner,
this->core->type.node, 0, this, node_bind_func, &this->global); this->core->type.node, 0, this, node_bind_func, &this->global);
update_info(this);
pw_node_update_state(this, PW_NODE_STATE_SUSPENDED, NULL); pw_node_update_state(this, PW_NODE_STATE_SUSPENDED, NULL);
} }
@ -617,6 +624,7 @@ do_node_remove_done(struct spa_loop *loop,
free(this->error); free(this->error);
if (this->properties) if (this->properties)
pw_properties_free(this->properties); pw_properties_free(this->properties);
clear_info(this);
free(impl); free(impl);
return SPA_RESULT_OK; return SPA_RESULT_OK;
@ -700,13 +708,13 @@ struct pw_port *pw_node_get_free_port(struct pw_node *node, enum pw_direction di
int i; int i;
if (direction == PW_DIRECTION_INPUT) { if (direction == PW_DIRECTION_INPUT) {
max_ports = node->max_input_ports; max_ports = node->info.max_input_ports;
n_ports = &node->n_input_ports; n_ports = &node->info.n_input_ports;
ports = &node->input_ports; ports = &node->input_ports;
portmap = node->input_port_map; portmap = node->input_port_map;
} else { } else {
max_ports = node->max_output_ports; max_ports = node->info.max_output_ports;
n_ports = &node->n_output_ports; n_ports = &node->info.n_output_ports;
ports = &node->output_ports; ports = &node->output_ports;
portmap = node->output_port_map; portmap = node->output_port_map;
} }
@ -843,7 +851,6 @@ void pw_node_update_state(struct pw_node *node, enum pw_node_state state, char *
old = node->state; old = node->state;
if (old != state) { if (old != state) {
struct pw_node_info info;
struct pw_resource *resource; struct pw_resource *resource;
pw_log_debug("node %p: update state from %s -> %s", node, pw_log_debug("node %p: update state from %s -> %s", node,
@ -856,15 +863,12 @@ void pw_node_update_state(struct pw_node *node, enum pw_node_state state, char *
pw_signal_emit(&node->state_changed, node, old, state); pw_signal_emit(&node->state_changed, node, old, state);
spa_zero(info); node->info.change_mask = 1 << 5;
info.change_mask = 1 << 5; node->info.state = node->state;
info.state = node->state; node->info.error = node->error;
info.error = node->error;
spa_list_for_each(resource, &node->resource_list, link) { spa_list_for_each(resource, &node->resource_list, link) {
/* global is only set when there are resources */ pw_node_notify_info(resource, &node->info);
info.id = node->global->id;
pw_node_notify_info(resource, &info);
} }
} }
} }

View file

@ -51,6 +51,8 @@ struct pw_node {
struct pw_client *owner; struct pw_client *owner;
char *name; char *name;
struct pw_properties *properties; struct pw_properties *properties;
struct pw_node_info info;
enum pw_node_state state; enum pw_node_state state;
char *error; char *error;
PW_SIGNAL(state_request, (struct pw_listener *listener, PW_SIGNAL(state_request, (struct pw_listener *listener,
@ -68,14 +70,10 @@ struct pw_node {
PW_SIGNAL(initialized, (struct pw_listener *listener, struct pw_node *object)); PW_SIGNAL(initialized, (struct pw_listener *listener, struct pw_node *object));
uint32_t max_input_ports;
uint32_t n_input_ports;
struct spa_list input_ports; struct spa_list input_ports;
struct pw_port **input_port_map; struct pw_port **input_port_map;
uint32_t n_used_input_links; uint32_t n_used_input_links;
uint32_t max_output_ports;
uint32_t n_output_ports;
struct spa_list output_ports; struct spa_list output_ports;
struct pw_port **output_port_map; struct pw_port **output_port_map;
uint32_t n_used_output_links; uint32_t n_used_output_links;

View file

@ -433,16 +433,16 @@ static void node_marshal_info(void *object, struct pw_node_info *info)
SPA_POD_TYPE_INT, info->id, SPA_POD_TYPE_INT, info->id,
SPA_POD_TYPE_LONG, info->change_mask, SPA_POD_TYPE_LONG, info->change_mask,
SPA_POD_TYPE_STRING, info->name, SPA_POD_TYPE_STRING, info->name,
SPA_POD_TYPE_INT, info->max_inputs, SPA_POD_TYPE_INT, info->max_input_ports,
SPA_POD_TYPE_INT, info->n_inputs, SPA_POD_TYPE_INT, info->n_input_ports,
SPA_POD_TYPE_INT, info->n_input_formats, 0); SPA_POD_TYPE_INT, info->n_input_formats, 0);
for (i = 0; i < info->n_input_formats; i++) for (i = 0; i < info->n_input_formats; i++)
spa_pod_builder_add(&b.b, SPA_POD_TYPE_POD, info->input_formats[i], 0); spa_pod_builder_add(&b.b, SPA_POD_TYPE_POD, info->input_formats[i], 0);
spa_pod_builder_add(&b.b, spa_pod_builder_add(&b.b,
SPA_POD_TYPE_INT, info->max_outputs, SPA_POD_TYPE_INT, info->max_output_ports,
SPA_POD_TYPE_INT, info->n_outputs, SPA_POD_TYPE_INT, info->n_output_ports,
SPA_POD_TYPE_INT, info->n_output_formats, 0); SPA_POD_TYPE_INT, info->n_output_formats, 0);
for (i = 0; i < info->n_output_formats; i++) for (i = 0; i < info->n_output_formats; i++)
@ -883,7 +883,8 @@ static void link_marshal_info(void *object, struct pw_link_info *info)
SPA_POD_TYPE_INT, info->output_node_id, SPA_POD_TYPE_INT, info->output_node_id,
SPA_POD_TYPE_INT, info->output_port_id, SPA_POD_TYPE_INT, info->output_port_id,
SPA_POD_TYPE_INT, info->input_node_id, SPA_POD_TYPE_INT, info->input_node_id,
SPA_POD_TYPE_INT, info->input_port_id); SPA_POD_TYPE_INT, info->input_port_id,
SPA_POD_TYPE_POD, info->format);
pw_connection_end_write(connection, resource->id, PW_LINK_EVENT_INFO, b.b.offset); pw_connection_end_write(connection, resource->id, PW_LINK_EVENT_INFO, b.b.offset);
} }

View file

@ -104,12 +104,12 @@ dump_node_info(struct pw_context *c, int res, const struct pw_node_info *info, v
int i; int i;
printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name); printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
printf("%c\tinputs: %u/%u\n", MARK_CHANGE(1), info->n_inputs, info->max_inputs); printf("%c\tinput ports: %u/%u\n", MARK_CHANGE(1), info->n_input_ports, info->max_input_ports);
printf("%c\tinput formats:\n", MARK_CHANGE(2)); printf("%c\tinput formats:\n", MARK_CHANGE(2));
for (i = 0; i < info->n_input_formats; i++) for (i = 0; i < info->n_input_formats; i++)
spa_debug_format(info->input_formats[i], c->type.map); spa_debug_format(info->input_formats[i], c->type.map);
printf("%c\toutputs: %u/%u\n", MARK_CHANGE(3), info->n_outputs, info->max_outputs); printf("%c\toutput ports: %u/%u\n", MARK_CHANGE(3), info->n_output_ports, info->max_output_ports);
printf("%c\toutput formats:\n", MARK_CHANGE(4)); printf("%c\toutput formats:\n", MARK_CHANGE(4));
for (i = 0; i < info->n_output_formats; i++) for (i = 0; i < info->n_output_formats; i++)
spa_debug_format(info->output_formats[i], c->type.map); spa_debug_format(info->output_formats[i], c->type.map);
@ -162,6 +162,11 @@ dump_link_info(struct pw_context *c, int res, const struct pw_link_info *info, v
printf("%c\toutput-port-id: %u\n", MARK_CHANGE(1), info->output_port_id); printf("%c\toutput-port-id: %u\n", MARK_CHANGE(1), info->output_port_id);
printf("%c\tinput-node-id: %u\n", MARK_CHANGE(2), info->input_node_id); printf("%c\tinput-node-id: %u\n", MARK_CHANGE(2), info->input_node_id);
printf("%c\tinput-port-id: %u\n", MARK_CHANGE(3), info->input_port_id); printf("%c\tinput-port-id: %u\n", MARK_CHANGE(3), info->input_port_id);
printf("%c\tformat:\n", MARK_CHANGE(4));
if (info->format)
spa_debug_format(info->format, c->type.map);
else
printf("\t none\n");
} }
} }