mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
link: add link state and error to info
Notify when state changes
This commit is contained in:
parent
0358e8b480
commit
f3dfe61aa0
6 changed files with 68 additions and 42 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue