diff --git a/src/modules/module-protocol-pulse/manager.c b/src/modules/module-protocol-pulse/manager.c index c4942aab4..97a05e14b 100644 --- a/src/modules/module-protocol-pulse/manager.c +++ b/src/modules/module-protocol-pulse/manager.c @@ -73,24 +73,45 @@ static void core_sync(struct manager *m) pw_log_debug("sync start %u", m->sync_seq); } +static uint32_t clear_params(struct spa_list *param_list, uint32_t id) +{ + struct pw_manager_param *p, *t; + uint32_t count = 0; + + spa_list_for_each_safe(p, t, param_list, link) { + if (id == SPA_ID_INVALID || p->id == id) { + spa_list_remove(&p->link); + free(p); + count++; + } + } + return count; +} + static struct pw_manager_param *add_param(struct spa_list *params, uint32_t id, const struct spa_pod *param) { struct pw_manager_param *p; - if (param == NULL || !spa_pod_is_object(param)) { - errno = EINVAL; - return NULL; - } - if (id == SPA_ID_INVALID) + if (id == SPA_ID_INVALID) { + if (param == NULL || !spa_pod_is_object(param)) { + errno = EINVAL; + return NULL; + } id = SPA_POD_OBJECT_ID(param); + } - p = malloc(sizeof(*p) + SPA_POD_SIZE(param)); + p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0)); if (p == NULL) return NULL; p->id = id; - p->param = SPA_MEMBER(p, sizeof(*p), struct spa_pod); - memcpy(p->param, param, SPA_POD_SIZE(param)); + if (param != NULL) { + p->param = SPA_MEMBER(p, sizeof(*p), struct spa_pod); + memcpy(p->param, param, SPA_POD_SIZE(param)); + } else { + clear_params(params, id); + p->param = NULL; + } spa_list_append(params, &p->link); return p; @@ -108,21 +129,6 @@ static bool has_param(struct spa_list *param_list, struct pw_manager_param *p) return false; } -static uint32_t clear_params(struct spa_list *param_list, uint32_t id) -{ - struct pw_manager_param *p, *t; - uint32_t count = 0; - - spa_list_for_each_safe(p, t, param_list, link) { - if (id == SPA_ID_INVALID || p->id == id) { - spa_list_remove(&p->link); - free(p); - count++; - } - } - return count; -} - static struct object *find_object(struct manager *m, uint32_t id) { @@ -140,12 +146,14 @@ static void object_update_params(struct object *o) { struct pw_manager_param *p; - spa_list_for_each(p, &o->pending_list, link) - clear_params(&o->this.param_list, p->id); - spa_list_consume(p, &o->pending_list, link) { spa_list_remove(&p->link); - spa_list_append(&o->this.param_list, &p->link); + if (p->param == NULL) { + clear_params(&o->this.param_list, p->id); + free(p); + } else { + spa_list_append(&o->this.param_list, &p->link); + } } } @@ -277,7 +285,7 @@ static void device_event_info(void *object, const struct pw_device_info *info) case SPA_PARAM_Route: break; } - clear_params(&o->pending_list, id); + add_param(&o->pending_list, id, NULL); if (!(info->params[i].flags & SPA_PARAM_INFO_READ)) continue; @@ -382,7 +390,7 @@ static void node_event_info(void *object, const struct pw_node_info *info) info->params[i].user = 0; changed++; - clear_params(&o->pending_list, id); + add_param(&o->pending_list, id, NULL); if (!(info->params[i].flags & SPA_PARAM_INFO_READ)) continue; diff --git a/src/pipewire/impl-device.c b/src/pipewire/impl-device.c index 0aeb8610d..5deee792e 100644 --- a/src/pipewire/impl-device.c +++ b/src/pipewire/impl-device.c @@ -741,7 +741,7 @@ static void device_info(void *data, const struct spa_device_info *info) continue; pw_log_debug(NAME" %p: update param %d", device, id); - pw_param_clear(&impl->pending_list, id); + pw_param_add(&impl->pending_list, id, NULL); device->info.params[i] = info->params[i]; device->info.params[i].user = 0; diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index a2c72bc1c..61844dedf 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -1286,7 +1286,7 @@ static void node_info(void *data, const struct spa_node_info *info) continue; pw_log_debug(NAME" %p: update param %d", node, id); - pw_param_clear(&impl->pending_list, id); + pw_param_add(&impl->pending_list, id, NULL); node->info.params[i] = info->params[i]; node->info.params[i].user = 0; diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index b01581d38..abfd1b02b 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -378,7 +378,7 @@ static void update_info(struct pw_impl_port *port, const struct spa_port_info *i continue; pw_log_debug(NAME" %p: update param %d", port, id); - pw_param_clear(&impl->pending_list, id); + pw_param_add(&impl->pending_list, id, NULL); port->info.params[i] = info->params[i]; port->info.params[i].user = 0; diff --git a/src/pipewire/private.h b/src/pipewire/private.h index d8d8c3166..9830bf823 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -90,28 +90,6 @@ struct pw_param { struct spa_pod *param; }; -static inline struct pw_param *pw_param_add(struct spa_list *params, - uint32_t id, const struct spa_pod *param) -{ - struct pw_param *p; - - if (param == NULL || !spa_pod_is_object(param)) { - errno = EINVAL; - return NULL; - } - if (id == SPA_ID_INVALID) - id = SPA_POD_OBJECT_ID(param); - - if ((p = malloc(sizeof(*p) + SPA_POD_SIZE(param))) == NULL) - return NULL; - - p->id = id; - p->param = SPA_MEMBER(p, sizeof(*p), struct spa_pod); - memcpy(p->param, param, SPA_POD_SIZE(param)); - spa_list_append(params, &p->link); - return p; -} - static inline uint32_t pw_param_clear(struct spa_list *param_list, uint32_t id) { struct pw_param *p, *t; @@ -127,16 +105,46 @@ static inline uint32_t pw_param_clear(struct spa_list *param_list, uint32_t id) return count; } +static inline struct pw_param *pw_param_add(struct spa_list *params, + uint32_t id, const struct spa_pod *param) +{ + struct pw_param *p; + + if (id == SPA_ID_INVALID) { + if (param == NULL || !spa_pod_is_object(param)) { + errno = EINVAL; + return NULL; + } + id = SPA_POD_OBJECT_ID(param); + } + + if ((p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0))) == NULL) + return NULL; + + p->id = id; + if (param != NULL) { + p->param = SPA_MEMBER(p, sizeof(*p), struct spa_pod); + memcpy(p->param, param, SPA_POD_SIZE(param)); + } else { + pw_param_clear(params, id); + p->param = NULL; + } + spa_list_append(params, &p->link); + return p; +} + static inline void pw_param_update(struct spa_list *param_list, struct spa_list *pending_list) { struct pw_param *p; - spa_list_for_each(p, pending_list, link) - pw_param_clear(param_list, p->id); - spa_list_consume(p, pending_list, link) { spa_list_remove(&p->link); - spa_list_append(param_list, &p->link); + if (p->param == NULL) { + pw_param_clear(param_list, p->id); + free(p); + } else { + spa_list_append(param_list, &p->link); + } } } diff --git a/src/tools/pw-dump.c b/src/tools/pw-dump.c index 03536224d..9d8e79918 100644 --- a/src/tools/pw-dump.c +++ b/src/tools/pw-dump.c @@ -122,29 +122,6 @@ static void core_sync(struct data *d) pw_log_debug("sync start %u", d->sync_seq); } -static struct param *add_param(struct spa_list *params, uint32_t id, const struct spa_pod *param) -{ - struct param *p; - - if (param == NULL || !spa_pod_is_object(param)) { - errno = EINVAL; - return NULL; - } - if (id == SPA_ID_INVALID) - id = SPA_POD_OBJECT_ID(param); - - p = malloc(sizeof(*p) + SPA_POD_SIZE(param)); - if (p == NULL) - return NULL; - - p->id = id; - p->param = SPA_MEMBER(p, sizeof(*p), struct spa_pod); - memcpy(p->param, param, SPA_POD_SIZE(param)); - spa_list_append(params, &p->link); - - return p; -} - static uint32_t clear_params(struct spa_list *param_list, uint32_t id) { struct param *p, *t; @@ -160,6 +137,35 @@ static uint32_t clear_params(struct spa_list *param_list, uint32_t id) return count; } +static struct param *add_param(struct spa_list *params, uint32_t id, const struct spa_pod *param) +{ + struct param *p; + + if (id == SPA_ID_INVALID) { + if (param == NULL || !spa_pod_is_object(param)) { + errno = EINVAL; + return NULL; + } + id = SPA_POD_OBJECT_ID(param); + } + + p = malloc(sizeof(*p) + (param != NULL ? SPA_POD_SIZE(param) : 0)); + if (p == NULL) + return NULL; + + p->id = id; + if (param != NULL) { + p->param = SPA_MEMBER(p, sizeof(*p), struct spa_pod); + memcpy(p->param, param, SPA_POD_SIZE(param)); + } else { + clear_params(params, id); + p->param = NULL; + } + spa_list_append(params, &p->link); + + return p; +} + static struct object *find_object(struct data *d, uint32_t id) { struct object *o; @@ -174,12 +180,14 @@ static void object_update_params(struct object *o) { struct param *p; - spa_list_for_each(p, &o->pending_list, link) - clear_params(&o->param_list, p->id); - spa_list_consume(p, &o->pending_list, link) { spa_list_remove(&p->link); - spa_list_append(&o->param_list, &p->link); + if (p->param == NULL) { + clear_params(&o->param_list, p->id); + free(p); + } else { + spa_list_append(&o->param_list, &p->link); + } } } @@ -482,7 +490,7 @@ static void put_params(struct data *d, const char *key, put_begin(d, spa_debug_type_find_short_name(spa_type_param, pi->id), "[", flags); spa_list_for_each(p, list, link) { - if (p->id == pi->id && flags == 0) + if (p->id == pi->id) put_pod(d, NULL, p->param); } put_end(d, "]", flags); @@ -834,7 +842,7 @@ static void node_event_info(void *object, const struct pw_node_info *info) info->params[i].user = 0; changed++; - clear_params(&o->pending_list, id); + add_param(&o->pending_list, id, NULL); if (!(info->params[i].flags & SPA_PARAM_INFO_READ)) continue; @@ -917,7 +925,7 @@ static void port_event_info(void *object, const struct pw_port_info *info) info->params[i].user = 0; changed++; - clear_params(&o->pending_list, id); + add_param(&o->pending_list, id, NULL); if (!(info->params[i].flags & SPA_PARAM_INFO_READ)) continue;