mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-11 13:30:07 -05:00
stream: remove READ flag when removing params
Clear the READ flag when the param is removed. Don't recursively emit param_changed events or we could end up in an infite loop when we update params from param_changed.
This commit is contained in:
parent
0e516dec44
commit
aaa91b2b7e
2 changed files with 87 additions and 9 deletions
|
|
@ -152,6 +152,7 @@ struct filter {
|
|||
unsigned int process_rt:1;
|
||||
unsigned int driving:1;
|
||||
unsigned int trigger:1;
|
||||
int in_emit_param_changed;
|
||||
};
|
||||
|
||||
static int get_param_index(uint32_t id)
|
||||
|
|
@ -276,6 +277,8 @@ static void clear_params(struct filter *impl, struct port *port, uint32_t id)
|
|||
{
|
||||
struct param *p, *t;
|
||||
struct spa_list *param_list;
|
||||
bool found = false;
|
||||
int i, idx;
|
||||
|
||||
if (port)
|
||||
param_list = &port->param_list;
|
||||
|
|
@ -285,10 +288,42 @@ static void clear_params(struct filter *impl, struct port *port, uint32_t id)
|
|||
spa_list_for_each_safe(p, t, param_list, link) {
|
||||
if (id == SPA_ID_INVALID ||
|
||||
(p->id == id && !(p->flags & PARAM_FLAG_LOCKED))) {
|
||||
found = true;
|
||||
spa_list_remove(&p->link);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
if (id == SPA_ID_INVALID) {
|
||||
if (port) {
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
for (i = 0; i < N_PORT_PARAMS; i++) {
|
||||
port->params[i].flags &= ~SPA_PARAM_INFO_READ;
|
||||
port->params[i].user++;
|
||||
}
|
||||
} else {
|
||||
impl->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
|
||||
for (i = 0; i < N_NODE_PARAMS; i++) {
|
||||
impl->params[i].flags &= ~SPA_PARAM_INFO_READ;
|
||||
impl->params[i].user++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (port) {
|
||||
if ((idx = get_port_param_index(id)) != -1) {
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
port->params[idx].flags &= ~SPA_PARAM_INFO_READ;
|
||||
port->params[idx].user++;
|
||||
}
|
||||
} else {
|
||||
if ((idx = get_param_index(id)) != -1) {
|
||||
impl->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
|
||||
impl->params[idx].flags &= ~SPA_PARAM_INFO_READ;
|
||||
impl->params[idx].user++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct port *alloc_port(struct filter *filter,
|
||||
|
|
@ -434,12 +469,19 @@ static int impl_enum_params(void *object, int seq, uint32_t id, uint32_t start,
|
|||
return enum_params(impl, &impl->param_list, seq, id, start, num, filter);
|
||||
}
|
||||
|
||||
static inline void emit_param_changed(struct filter *impl, void *port,
|
||||
uint32_t id, const struct spa_pod *param)
|
||||
{
|
||||
struct pw_filter *filter = &impl->this;
|
||||
if (impl->in_emit_param_changed++ == 0)
|
||||
pw_filter_emit_param_changed(filter, port, id, param);
|
||||
impl->in_emit_param_changed--;
|
||||
}
|
||||
|
||||
static int impl_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param)
|
||||
{
|
||||
struct filter *impl = object;
|
||||
struct pw_filter *filter = &impl->this;
|
||||
|
||||
pw_filter_emit_param_changed(filter, NULL, id, param);
|
||||
emit_param_changed(impl, NULL, id, param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -777,7 +819,6 @@ static int default_latency(struct filter *impl, struct port *port, enum spa_dire
|
|||
|
||||
static int handle_latency(struct filter *impl, struct port *port, const struct spa_pod *param)
|
||||
{
|
||||
struct pw_filter *filter = &impl->this;
|
||||
struct spa_latency_info info;
|
||||
int res;
|
||||
|
||||
|
|
@ -797,7 +838,7 @@ static int handle_latency(struct filter *impl, struct port *port, const struct s
|
|||
return 0;
|
||||
|
||||
if (SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_CUSTOM_LATENCY)) {
|
||||
pw_filter_emit_param_changed(filter, port->user_data,
|
||||
emit_param_changed(impl, port->user_data,
|
||||
SPA_PARAM_Latency, param);
|
||||
} else {
|
||||
default_latency(impl, port, info.direction);
|
||||
|
|
@ -849,7 +890,7 @@ static int impl_port_set_param(void *object,
|
|||
}
|
||||
|
||||
if (emit)
|
||||
pw_filter_emit_param_changed(filter, port->user_data, id, param);
|
||||
emit_param_changed(impl, port->user_data, id, param);
|
||||
|
||||
if (filter->state == PW_FILTER_STATE_ERROR)
|
||||
return filter->error_res;
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ struct stream {
|
|||
unsigned int using_trigger:1;
|
||||
unsigned int trigger:1;
|
||||
int in_set_param;
|
||||
int in_emit_param_changed;
|
||||
};
|
||||
|
||||
static int get_param_index(uint32_t id)
|
||||
|
|
@ -268,14 +269,42 @@ static struct param *add_param(struct stream *impl,
|
|||
static void clear_params(struct stream *impl, uint32_t id)
|
||||
{
|
||||
struct param *p, *t;
|
||||
bool found = false;
|
||||
int i, idx;
|
||||
|
||||
spa_list_for_each_safe(p, t, &impl->param_list, link) {
|
||||
if (id == SPA_ID_INVALID ||
|
||||
(p->id == id && !(p->flags & PARAM_FLAG_LOCKED))) {
|
||||
found = true;
|
||||
spa_list_remove(&p->link);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
if (id == SPA_ID_INVALID) {
|
||||
impl->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
|
||||
for (i = 0; i < N_NODE_PARAMS; i++) {
|
||||
impl->params[i].flags &= ~SPA_PARAM_INFO_READ;
|
||||
impl->params[i].user++;
|
||||
}
|
||||
impl->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
for (i = 0; i < N_PORT_PARAMS; i++) {
|
||||
impl->port_params[i].flags &= ~SPA_PARAM_INFO_READ;
|
||||
impl->port_params[i].user++;
|
||||
}
|
||||
} else {
|
||||
if ((idx = get_param_index(id)) != -1) {
|
||||
impl->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
|
||||
impl->params[idx].flags &= ~SPA_PARAM_INFO_READ;
|
||||
impl->params[idx].user++;
|
||||
}
|
||||
if ((idx = get_port_param_index(id)) != -1) {
|
||||
impl->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
impl->port_params[idx].flags &= ~SPA_PARAM_INFO_READ;
|
||||
impl->port_params[idx].user++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int update_params(struct stream *impl, uint32_t id,
|
||||
|
|
@ -563,16 +592,24 @@ static int impl_enum_params(void *object, int seq, uint32_t id, uint32_t start,
|
|||
return enum_params(object, false, seq, id, start, num, filter);
|
||||
}
|
||||
|
||||
static inline void emit_param_changed(struct stream *impl,
|
||||
uint32_t id, const struct spa_pod *param)
|
||||
{
|
||||
struct pw_stream *stream = &impl->this;
|
||||
if (impl->in_emit_param_changed++ == 0)
|
||||
pw_stream_emit_param_changed(stream, id, param);
|
||||
impl->in_emit_param_changed--;
|
||||
}
|
||||
|
||||
static int impl_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param)
|
||||
{
|
||||
struct stream *impl = object;
|
||||
struct pw_stream *stream = &impl->this;
|
||||
|
||||
if (id != SPA_PARAM_Props)
|
||||
return -ENOTSUP;
|
||||
|
||||
if (impl->in_set_param == 0)
|
||||
pw_stream_emit_param_changed(stream, id, param);
|
||||
emit_param_changed(impl, id, param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -885,7 +922,7 @@ static int impl_port_set_param(void *object,
|
|||
break;
|
||||
}
|
||||
|
||||
pw_stream_emit_param_changed(stream, id, param);
|
||||
emit_param_changed(impl, id, param);
|
||||
|
||||
if (stream->state == PW_STREAM_STATE_ERROR)
|
||||
return stream->error_res;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue