From 15a4d9a9df07119a4a6c9e53d0756f6b2bfeffe2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 4 Feb 2024 10:58:41 +0100 Subject: [PATCH] stream: fix param emission for Props Props set on the node directly should also result in emission of changed notify when required, just like we do for params set on the port. This accidentally used to be done because stream_update_params() unconditionally used to emit this for us. But commit 94cde3090ebddf98cf21698ebbeeefe2d02fde1f changed that. Fixes #3833 --- src/pipewire/stream.c | 86 +++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index d33380749..51f6d2f06 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -607,9 +607,50 @@ static inline void emit_param_changed(struct stream *impl, impl->in_emit_param_changed--; } +static void emit_node_info(struct stream *d, bool full) +{ + uint32_t i; + uint64_t old = full ? d->info.change_mask : 0; + if (full) + d->info.change_mask = d->change_mask_all; + if (d->info.change_mask != 0) { + if (d->info.change_mask & SPA_NODE_CHANGE_MASK_PARAMS) { + for (i = 0; i < d->info.n_params; i++) { + if (d->params[i].user > 0) { + d->params[i].flags ^= SPA_PARAM_INFO_SERIAL; + d->params[i].user = 0; + } + } + } + spa_node_emit_info(&d->hooks, &d->info); + } + d->info.change_mask = old; +} + +static void emit_port_info(struct stream *d, bool full) +{ + uint32_t i; + uint64_t old = full ? d->port_info.change_mask : 0; + if (full) + d->port_info.change_mask = d->port_change_mask_all; + if (d->port_info.change_mask != 0) { + if (d->port_info.change_mask & SPA_PORT_CHANGE_MASK_PARAMS) { + for (i = 0; i < d->port_info.n_params; i++) { + if (d->port_params[i].user > 0) { + d->port_params[i].flags ^= SPA_PARAM_INFO_SERIAL; + d->port_params[i].user = 0; + } + } + } + spa_node_emit_port_info(&d->hooks, d->direction, 0, &d->port_info); + } + d->port_info.change_mask = old; +} + 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; @@ -617,6 +658,11 @@ static int impl_set_param(void *object, uint32_t id, uint32_t flags, const struc if (impl->in_set_param == 0) emit_param_changed(impl, id, param); + if (stream->state == PW_STREAM_STATE_ERROR) + return stream->error_res; + + emit_node_info(impl, false); + emit_port_info(impl, false); return 0; } @@ -686,46 +732,6 @@ static int impl_send_command(void *object, const struct spa_command *command) return 0; } -static void emit_node_info(struct stream *d, bool full) -{ - uint32_t i; - uint64_t old = full ? d->info.change_mask : 0; - if (full) - d->info.change_mask = d->change_mask_all; - if (d->info.change_mask != 0) { - if (d->info.change_mask & SPA_NODE_CHANGE_MASK_PARAMS) { - for (i = 0; i < d->info.n_params; i++) { - if (d->params[i].user > 0) { - d->params[i].flags ^= SPA_PARAM_INFO_SERIAL; - d->params[i].user = 0; - } - } - } - spa_node_emit_info(&d->hooks, &d->info); - } - d->info.change_mask = old; -} - -static void emit_port_info(struct stream *d, bool full) -{ - uint32_t i; - uint64_t old = full ? d->port_info.change_mask : 0; - if (full) - d->port_info.change_mask = d->port_change_mask_all; - if (d->port_info.change_mask != 0) { - if (d->port_info.change_mask & SPA_PORT_CHANGE_MASK_PARAMS) { - for (i = 0; i < d->port_info.n_params; i++) { - if (d->port_params[i].user > 0) { - d->port_params[i].flags ^= SPA_PARAM_INFO_SERIAL; - d->port_params[i].user = 0; - } - } - } - spa_node_emit_port_info(&d->hooks, d->direction, 0, &d->port_info); - } - d->port_info.change_mask = old; -} - static int impl_add_listener(void *object, struct spa_hook *listener, const struct spa_node_events *events,