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->input_node_id,
|
||||
"i", info->input_port_id,
|
||||
"i", info->state,
|
||||
"s", info->error,
|
||||
"P", info->format,
|
||||
"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.input_node_id,
|
||||
"i", &info.input_port_id,
|
||||
"i", &info.state,
|
||||
"s", &info.error,
|
||||
"P", &info.format,
|
||||
"i", &props.n_items, NULL) < 0)
|
||||
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_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 (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)
|
||||
{
|
||||
if (info->error)
|
||||
free((void *) info->error);
|
||||
if (info->format)
|
||||
free(info->format);
|
||||
if (info->props)
|
||||
|
|
|
|||
|
|
@ -204,13 +204,16 @@ struct pw_link_info {
|
|||
uint32_t id; /**< id of the global */
|
||||
#define PW_LINK_CHANGE_MASK_OUTPUT (1 << 0)
|
||||
#define PW_LINK_CHANGE_MASK_INPUT (1 << 1)
|
||||
#define PW_LINK_CHANGE_MASK_FORMAT (1 << 2)
|
||||
#define PW_LINK_CHANGE_MASK_PROPS (1 << 3)
|
||||
#define PW_LINK_CHANGE_MASK_STATE (1 << 2)
|
||||
#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 */
|
||||
uint32_t output_node_id; /**< server side output node id */
|
||||
uint32_t output_port_id; /**< output port id */
|
||||
uint32_t input_node_id; /**< server side input node 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_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)
|
||||
{
|
||||
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) {
|
||||
struct pw_node *in = link->input->node, *out = link->output->node;
|
||||
if (state == old)
|
||||
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 (link->error)
|
||||
free(link->error);
|
||||
link->error = error;
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
link->info.change_mask |= PW_LINK_CHANGE_MASK_STATE;
|
||||
pw_link_events_info_changed(link, &link->info);
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
return 0;
|
||||
|
||||
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,
|
||||
do_activate_link, SPA_ID_INVALID, NULL, 0, false, this);
|
||||
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;
|
||||
int in_mix_state, out_mix_state;
|
||||
|
||||
if (this->state == PW_LINK_STATE_ERROR)
|
||||
if (this->info.state == PW_LINK_STATE_ERROR)
|
||||
return -EIO;
|
||||
|
||||
input = this->input;
|
||||
|
|
@ -1318,7 +1327,7 @@ struct pw_link *pw_link_new(struct pw_core *core,
|
|||
|
||||
this->core = core;
|
||||
this->properties = properties;
|
||||
this->state = PW_LINK_STATE_INIT;
|
||||
this->info.state = PW_LINK_STATE_INIT;
|
||||
|
||||
this->input = input;
|
||||
this->output = output;
|
||||
|
|
|
|||
|
|
@ -462,9 +462,6 @@ struct pw_link {
|
|||
struct pw_properties *properties; /**< extra link properties */
|
||||
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_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\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\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)
|
||||
spa_debug_format(2, NULL, info->format);
|
||||
else
|
||||
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