diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c index c227ef1e1..422c6f1a6 100644 --- a/spa/plugins/audioconvert/audioconvert.c +++ b/spa/plugins/audioconvert/audioconvert.c @@ -1828,6 +1828,8 @@ static int reconfigure_mode(struct impl *this, enum spa_param_port_config_mode m i = dir->n_ports++; init_port(this, direction, i, 0, false, false, true); } + /* emit all port changes */ + emit_info(this, false); this->info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS | SPA_NODE_CHANGE_MASK_PARAMS; this->info.flags &= ~SPA_NODE_FLAG_NEED_CONFIGURE; @@ -1836,88 +1838,99 @@ static int reconfigure_mode(struct impl *this, enum spa_param_port_config_mode m return 0; } -static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, - const struct spa_pod *param) +static int node_set_param_port_config(struct impl *this, uint32_t flags, + const struct spa_pod *param) { - struct impl *this = object; - - spa_return_val_if_fail(this != NULL, -EINVAL); + struct spa_audio_info info = { 0, }, *infop = NULL; + struct spa_pod *format = NULL; + enum spa_direction direction; + enum spa_param_port_config_mode mode; + bool monitor = false, control = false; + int res; if (param == NULL) return 0; - switch (id) { - case SPA_PARAM_PortConfig: - { - struct spa_audio_info info = { 0, }, *infop = NULL; - struct spa_pod *format = NULL; - enum spa_direction direction; - enum spa_param_port_config_mode mode; - bool monitor = false, control = false; - int res; + if (spa_pod_parse_object(param, + SPA_TYPE_OBJECT_ParamPortConfig, NULL, + SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(&direction), + SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(&mode), + SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_OPT_Bool(&monitor), + SPA_PARAM_PORT_CONFIG_control, SPA_POD_OPT_Bool(&control), + SPA_PARAM_PORT_CONFIG_format, SPA_POD_OPT_Pod(&format)) < 0) + return -EINVAL; - if (spa_pod_parse_object(param, - SPA_TYPE_OBJECT_ParamPortConfig, NULL, - SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(&direction), - SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(&mode), - SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_OPT_Bool(&monitor), - SPA_PARAM_PORT_CONFIG_control, SPA_POD_OPT_Bool(&control), - SPA_PARAM_PORT_CONFIG_format, SPA_POD_OPT_Pod(&format)) < 0) + if (format) { + if (!spa_pod_is_object_type(format, SPA_TYPE_OBJECT_Format)) return -EINVAL; - if (format) { - if (!spa_pod_is_object_type(format, SPA_TYPE_OBJECT_Format)) - return -EINVAL; - - if ((res = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0) - return res; - - if (info.media_type != SPA_MEDIA_TYPE_audio || - info.media_subtype != SPA_MEDIA_SUBTYPE_raw) - return -EINVAL; - - if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) - return -EINVAL; - - if (info.info.raw.channels == 0 || - info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) - return -EINVAL; - - infop = &info; - } - - if ((res = reconfigure_mode(this, mode, direction, monitor, control, infop)) < 0) + if ((res = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0) return res; - break; + + if (info.media_type != SPA_MEDIA_TYPE_audio || + info.media_subtype != SPA_MEDIA_SUBTYPE_raw) + return -EINVAL; + + if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) + return -EINVAL; + + if (info.info.raw.channels == 0 || + info.info.raw.channels > SPA_AUDIO_MAX_CHANNELS) + return -EINVAL; + + infop = &info; } + return reconfigure_mode(this, mode, direction, monitor, control, infop); +} + +static int node_set_param_props(struct impl *this, uint32_t flags, + const struct spa_pod *param) +{ + bool have_graph = false; + struct filter_graph *g, *t; + + if (param == NULL) + return 0; + + this->filter_props_count = 0; + + spa_list_for_each_safe(g, t, &this->active_graphs, link) { + if (g->removing) + continue; + + have_graph = true; + this->in_filter_props++; + spa_filter_graph_set_props(g->graph, SPA_DIRECTION_INPUT, param); + this->filter_props_count++; + this->in_filter_props--; + } + if (!have_graph) + apply_props(this, param); + + clean_filter_handles(this, false); + return 0; +} + +static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, + const struct spa_pod *param) +{ + struct impl *this = object; + int res; + + spa_return_val_if_fail(this != NULL, -EINVAL); + + switch (id) { + case SPA_PARAM_PortConfig: + res = node_set_param_port_config(this, flags, param); + break; case SPA_PARAM_Props: - { - bool have_graph = false; - struct filter_graph *g, *t; - this->filter_props_count = 0; - - spa_list_for_each_safe(g, t, &this->active_graphs, link) { - if (g->removing) - continue; - - have_graph = true; - this->in_filter_props++; - spa_filter_graph_set_props(g->graph, - SPA_DIRECTION_INPUT, param); - this->filter_props_count++; - this->in_filter_props--; - } - if (!have_graph) - apply_props(this, param); - - clean_filter_handles(this, false); + res = node_set_param_props(this, flags, param); break; - } default: return -ENOENT; } emit_info(this, false); - return 0; + return res; } static int int32_cmp(const void *v1, const void *v2) diff --git a/spa/plugins/videoconvert/videoconvert-ffmpeg.c b/spa/plugins/videoconvert/videoconvert-ffmpeg.c index bdf4ba589..fa4e63849 100644 --- a/spa/plugins/videoconvert/videoconvert-ffmpeg.c +++ b/spa/plugins/videoconvert/videoconvert-ffmpeg.c @@ -472,10 +472,10 @@ static int init_port(struct impl *this, enum spa_direction direction, uint32_t p port->latency[SPA_DIRECTION_INPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT); port->latency[SPA_DIRECTION_OUTPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT); + port->info = SPA_PORT_INFO_INIT(); port->info.change_mask = port->info_all = SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_PROPS | SPA_PORT_CHANGE_MASK_PARAMS; - port->info = SPA_PORT_INFO_INIT(); port->info.flags = SPA_PORT_FLAG_NO_REF | SPA_PORT_FLAG_DYNAMIC_DATA; port->params[IDX_EnumFormat] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); @@ -788,6 +788,9 @@ static int reconfigure_mode(struct impl *this, enum spa_param_port_config_mode m init_port(this, direction, i, false, false, true); } + /* emit all port info first, then the node props and flags */ + emit_info(this, false); + this->info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS | SPA_NODE_CHANGE_MASK_PARAMS; this->info.flags &= ~SPA_NODE_FLAG_NEED_CONFIGURE; this->params[IDX_PortConfig].user++; @@ -795,57 +798,69 @@ static int reconfigure_mode(struct impl *this, enum spa_param_port_config_mode m return 0; } -static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, - const struct spa_pod *param) +static int node_set_param_port_config(struct impl *this, uint32_t flags, + const struct spa_pod *param) { - struct impl *this = object; - - spa_return_val_if_fail(this != NULL, -EINVAL); + struct spa_video_info info = { 0, }, *infop = NULL; + struct spa_pod *format = NULL; + enum spa_direction direction; + enum spa_param_port_config_mode mode; + bool monitor = false, control = false; + int res; if (param == NULL) return 0; - switch (id) { - case SPA_PARAM_PortConfig: - { - struct spa_video_info info = { 0, }, *infop = NULL; - struct spa_pod *format = NULL; - enum spa_direction direction; - enum spa_param_port_config_mode mode; - bool monitor = false, control = false; - int res; + if (spa_pod_parse_object(param, + SPA_TYPE_OBJECT_ParamPortConfig, NULL, + SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(&direction), + SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(&mode), + SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_OPT_Bool(&monitor), + SPA_PARAM_PORT_CONFIG_control, SPA_POD_OPT_Bool(&control), + SPA_PARAM_PORT_CONFIG_format, SPA_POD_OPT_Pod(&format)) < 0) + return -EINVAL; - if (spa_pod_parse_object(param, - SPA_TYPE_OBJECT_ParamPortConfig, NULL, - SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(&direction), - SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(&mode), - SPA_PARAM_PORT_CONFIG_monitor, SPA_POD_OPT_Bool(&monitor), - SPA_PARAM_PORT_CONFIG_control, SPA_POD_OPT_Bool(&control), - SPA_PARAM_PORT_CONFIG_format, SPA_POD_OPT_Pod(&format)) < 0) + if (format) { + if (!spa_pod_is_object_type(format, SPA_TYPE_OBJECT_Format)) return -EINVAL; - if (format) { - if (!spa_pod_is_object_type(format, SPA_TYPE_OBJECT_Format)) - return -EINVAL; - - if ((res = spa_format_video_parse(format, &info)) < 0) - return res; - - infop = &info; - } - - if ((res = reconfigure_mode(this, mode, direction, monitor, control, infop)) < 0) + if ((res = spa_format_video_parse(format, &info)) < 0) return res; - break; + + infop = &info; } + return reconfigure_mode(this, mode, direction, monitor, control, infop); +} + +static int node_set_param_props(struct impl *this, uint32_t flags, + const struct spa_pod *param) +{ + if (param == NULL) + return 0; + + apply_props(this, param); + return 0; +} +static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, + const struct spa_pod *param) +{ + struct impl *this = object; + int res; + + spa_return_val_if_fail(this != NULL, -EINVAL); + + switch (id) { + case SPA_PARAM_PortConfig: + res = node_set_param_port_config(this, flags, param); + break; case SPA_PARAM_Props: - apply_props(this, param); + res = node_set_param_props(this, flags, param); break; default: return -ENOENT; } emit_info(this, false); - return 0; + return res; } static inline void free_decoder(struct impl *this)