link: add link state and error to info

Notify when state changes
This commit is contained in:
Wim Taymans 2018-10-03 19:29:11 +02:00
parent 0358e8b480
commit f3dfe61aa0
6 changed files with 68 additions and 42 deletions

View file

@ -1034,6 +1034,8 @@ static void link_marshal_info(void *object, struct pw_link_info *info)
"i", info->output_port_id, "i", info->output_port_id,
"i", info->input_node_id, "i", info->input_node_id,
"i", info->input_port_id, "i", info->input_port_id,
"i", info->state,
"s", info->error,
"P", info->format, "P", info->format,
"i", n_items, NULL); "i", n_items, NULL);
@ -1064,6 +1066,8 @@ static int link_demarshal_info(void *object, void *data, size_t size)
"i", &info.output_port_id, "i", &info.output_port_id,
"i", &info.input_node_id, "i", &info.input_node_id,
"i", &info.input_port_id, "i", &info.input_port_id,
"i", &info.state,
"s", &info.error,
"P", &info.format, "P", &info.format,
"i", &props.n_items, NULL) < 0) "i", &props.n_items, NULL) < 0)
return -EINVAL; return -EINVAL;

View file

@ -399,6 +399,12 @@ 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;
info->input_port_id = update->input_port_id; info->input_port_id = update->input_port_id;
} }
if (update->change_mask & PW_LINK_CHANGE_MASK_STATE) {
info->state = update->state;
if (info->error)
free((void *) info->error);
info->error = update->error ? strdup(update->error) : NULL;
}
if (update->change_mask & PW_LINK_CHANGE_MASK_FORMAT) { if (update->change_mask & PW_LINK_CHANGE_MASK_FORMAT) {
if (info->format) if (info->format)
free(info->format); free(info->format);
@ -414,6 +420,8 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info,
void pw_link_info_free(struct pw_link_info *info) void pw_link_info_free(struct pw_link_info *info)
{ {
if (info->error)
free((void *) info->error);
if (info->format) if (info->format)
free(info->format); free(info->format);
if (info->props) if (info->props)

View file

@ -204,13 +204,16 @@ struct pw_link_info {
uint32_t id; /**< id of the global */ uint32_t id; /**< id of the global */
#define PW_LINK_CHANGE_MASK_OUTPUT (1 << 0) #define PW_LINK_CHANGE_MASK_OUTPUT (1 << 0)
#define PW_LINK_CHANGE_MASK_INPUT (1 << 1) #define PW_LINK_CHANGE_MASK_INPUT (1 << 1)
#define PW_LINK_CHANGE_MASK_FORMAT (1 << 2) #define PW_LINK_CHANGE_MASK_STATE (1 << 2)
#define PW_LINK_CHANGE_MASK_PROPS (1 << 3) #define PW_LINK_CHANGE_MASK_FORMAT (1 << 4)
#define PW_LINK_CHANGE_MASK_PROPS (1 << 4)
uint64_t change_mask; /**< bitfield of changed fields since last call */ uint64_t change_mask; /**< bitfield of changed fields since last call */
uint32_t output_node_id; /**< server side output node id */ uint32_t output_node_id; /**< server side output node id */
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 */
enum pw_link_state state; /**< the current state of the link */
const char *error; /**< an error reason if \a state is error */
struct spa_pod *format; /**< format over link */ struct spa_pod *format; /**< format over link */
struct spa_dict *props; /**< the properties of the link */ struct spa_dict *props; /**< the properties of the link */
}; };

View file

@ -88,44 +88,53 @@ static void debug_link(struct pw_link *link)
static void pw_link_update_state(struct pw_link *link, enum pw_link_state state, char *error) static void pw_link_update_state(struct pw_link *link, enum pw_link_state state, char *error)
{ {
enum pw_link_state old = link->state; enum pw_link_state old = link->info.state;
struct pw_node *in = link->input->node, *out = link->output->node;
struct pw_resource *resource;
if (state != old) { if (state == old)
struct pw_node *in = link->input->node, *out = link->output->node; return;
if (state == PW_LINK_STATE_ERROR) {
pw_log_error("link %p: update state %s -> error (%s)", link,
pw_link_state_as_string(old), error);
} else {
pw_log_debug("link %p: update state %s -> %s", link,
pw_link_state_as_string(old), pw_link_state_as_string(state));
}
link->state = state; if (state == PW_LINK_STATE_ERROR) {
if (link->error) pw_log_error("link %p: update state %s -> error (%s)", link,
free(link->error); pw_link_state_as_string(old), error);
link->error = error; } else {
pw_log_debug("link %p: update state %s -> %s", link,
pw_link_state_as_string(old), pw_link_state_as_string(state));
}
pw_link_events_state_changed(link, old, state, error); link->info.state = state;
if (link->info.error)
free((char*)link->info.error);
link->info.error = error;
debug_link(link); pw_link_events_state_changed(link, old, state, error);
if (old != PW_LINK_STATE_PAUSED && state == PW_LINK_STATE_PAUSED) { link->info.change_mask |= PW_LINK_CHANGE_MASK_STATE;
if (++out->n_ready_output_links == out->n_used_output_links) pw_link_events_info_changed(link, &link->info);
pw_node_set_state(out, PW_NODE_STATE_RUNNING);
if (++in->n_ready_input_links == in->n_used_input_links)
pw_node_set_state(in, PW_NODE_STATE_RUNNING);
pw_link_activate(link);
}
else if (old == PW_LINK_STATE_PAUSED && state < PW_LINK_STATE_PAUSED) {
if (--out->n_ready_output_links == 0 &&
out->n_ready_input_links == 0)
pw_node_set_state(out, PW_NODE_STATE_IDLE);
if (--in->n_ready_input_links == 0 &&
in->n_ready_output_links == 0)
pw_node_set_state(in, PW_NODE_STATE_IDLE);
}
spa_list_for_each(resource, &link->resource_list, link)
pw_link_resource_info(resource, &link->info);
link->info.change_mask = 0;
debug_link(link);
if (old != PW_LINK_STATE_PAUSED && state == PW_LINK_STATE_PAUSED) {
if (++out->n_ready_output_links == out->n_used_output_links)
pw_node_set_state(out, PW_NODE_STATE_RUNNING);
if (++in->n_ready_input_links == in->n_used_input_links)
pw_node_set_state(in, PW_NODE_STATE_RUNNING);
pw_link_activate(link);
}
else if (old == PW_LINK_STATE_PAUSED && state < PW_LINK_STATE_PAUSED) {
if (--out->n_ready_output_links == 0 &&
out->n_ready_input_links == 0)
pw_node_set_state(out, PW_NODE_STATE_IDLE);
if (--in->n_ready_input_links == 0 &&
in->n_ready_output_links == 0)
pw_node_set_state(in, PW_NODE_STATE_IDLE);
} }
} }
@ -852,14 +861,14 @@ int pw_link_activate(struct pw_link *this)
{ {
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
pw_log_debug("link %p: activate %d %d", this, impl->activated, this->state); pw_log_debug("link %p: activate %d %d", this, impl->activated, this->info.state);
if (impl->activated) if (impl->activated)
return 0; return 0;
pw_link_prepare(this); pw_link_prepare(this);
if (this->state == PW_LINK_STATE_PAUSED) { if (this->info.state == PW_LINK_STATE_PAUSED) {
pw_loop_invoke(this->output->node->data_loop, pw_loop_invoke(this->output->node->data_loop,
do_activate_link, SPA_ID_INVALID, NULL, 0, false, this); do_activate_link, SPA_ID_INVALID, NULL, 0, false, this);
impl->activated = true; impl->activated = true;
@ -874,7 +883,7 @@ static int check_states(struct pw_link *this, void *user_data, int res)
struct pw_port *input, *output; struct pw_port *input, *output;
int in_mix_state, out_mix_state; int in_mix_state, out_mix_state;
if (this->state == PW_LINK_STATE_ERROR) if (this->info.state == PW_LINK_STATE_ERROR)
return -EIO; return -EIO;
input = this->input; input = this->input;
@ -1318,7 +1327,7 @@ struct pw_link *pw_link_new(struct pw_core *core,
this->core = core; this->core = core;
this->properties = properties; this->properties = properties;
this->state = PW_LINK_STATE_INIT; this->info.state = PW_LINK_STATE_INIT;
this->input = input; this->input = input;
this->output = output; this->output = output;

View file

@ -462,9 +462,6 @@ struct pw_link {
struct pw_properties *properties; /**< extra link properties */ struct pw_properties *properties; /**< extra link properties */
bool feedback; bool feedback;
enum pw_link_state state; /**< link state */
char *error; /**< error message when state error */
struct spa_list resource_list; /**< list of bound resources */ struct spa_list resource_list; /**< list of bound resources */
struct spa_io_buffers *io; /**< link io area */ struct spa_io_buffers *io; /**< link io area */

View file

@ -426,12 +426,17 @@ static void link_event_info(void *object, struct pw_link_info *info)
printf("%c\toutput-port-id: %u\n", MARK_CHANGE(0), info->output_port_id); printf("%c\toutput-port-id: %u\n", MARK_CHANGE(0), info->output_port_id);
printf("%c\tinput-node-id: %u\n", MARK_CHANGE(1), info->input_node_id); printf("%c\tinput-node-id: %u\n", MARK_CHANGE(1), info->input_node_id);
printf("%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id); printf("%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id);
printf("%c\tformat:\n", MARK_CHANGE(2)); printf("%c\tstate: \"%s\"", MARK_CHANGE(2), pw_link_state_as_string(info->state));
if (info->state == PW_LINK_STATE_ERROR && info->error)
printf(" \"%s\"\n", info->error);
else
printf("\n");
printf("%c\tformat:\n", MARK_CHANGE(3));
if (info->format) if (info->format)
spa_debug_format(2, NULL, info->format); spa_debug_format(2, NULL, info->format);
else else
printf("\t\tnone\n"); printf("\t\tnone\n");
print_properties(info->props, MARK_CHANGE(3)); print_properties(info->props, MARK_CHANGE(4));
} }
} }