diff --git a/spa/plugins/audioconvert/audioadapter.c b/spa/plugins/audioconvert/audioadapter.c index c80c54a99..295b65044 100644 --- a/spa/plugins/audioconvert/audioadapter.c +++ b/spa/plugins/audioconvert/audioadapter.c @@ -1413,6 +1413,20 @@ static const struct spa_node_events follower_node_events = { .event = follower_event, }; +static void follower_probe_info(void *data, const struct spa_node_info *info) +{ + struct impl *this = data; + if (info->max_input_ports > 0) + this->direction = SPA_DIRECTION_INPUT; + else + this->direction = SPA_DIRECTION_OUTPUT; +} + +static const struct spa_node_events follower_probe_events = { + SPA_VERSION_NODE_EVENTS, + .info = follower_probe_info, +}; + static int follower_ready(void *data, int status) { struct impl *this = data; @@ -1775,23 +1789,36 @@ static int load_converter(struct impl *this, const struct spa_dict *info, struct spa_handle *hnd_convert = NULL; void *iface_conv = NULL; bool unload_handle = false; + struct spa_dict_item *items; + struct spa_dict cinfo; + char direction[16]; + uint32_t i; - if (info) - factory_name = spa_dict_lookup(info, "audio.adapt.converter"); + items = alloca((info->n_items + 1) * sizeof(struct spa_dict_item)); + cinfo = SPA_DICT(items, 0); + for (i = 0; i < info->n_items; i++) + items[cinfo.n_items++] = info->items[i]; + + snprintf(direction, sizeof(direction), "%s", + SPA_DIRECTION_REVERSE(this->direction) == SPA_DIRECTION_INPUT ? + "input" : "output"); + items[cinfo.n_items++] = SPA_DICT_ITEM("convert.direction", direction); + + factory_name = spa_dict_lookup(&cinfo, "audio.adapt.converter"); if (factory_name == NULL) factory_name = SPA_NAME_AUDIO_CONVERT; if (spa_streq(factory_name, SPA_NAME_AUDIO_CONVERT)) { - size_t size = spa_handle_factory_get_size(&spa_audioconvert_factory, info); + size_t size = spa_handle_factory_get_size(&spa_audioconvert_factory, &cinfo); hnd_convert = calloc(1, size); if (hnd_convert == NULL) return -errno; spa_handle_factory_init(&spa_audioconvert_factory, - hnd_convert, info, support, n_support); + hnd_convert, &cinfo, support, n_support); } else if (this->ploader) { - hnd_convert = spa_plugin_loader_load(this->ploader, factory_name, info); + hnd_convert = spa_plugin_loader_load(this->ploader, factory_name, &cinfo); if (!hnd_convert) return -EINVAL; unload_handle = true; @@ -1973,6 +2000,7 @@ impl_init(const struct spa_handle_factory *factory, struct impl *this; const char *str; int ret; + struct spa_hook probe_listener; spa_return_val_if_fail(factory != NULL, -EINVAL); spa_return_val_if_fail(handle != NULL, -EINVAL); @@ -2007,6 +2035,11 @@ impl_init(const struct spa_handle_factory *factory, SPA_VERSION_NODE, &impl_node, this); + /* just probe the ports to get the direction */ + spa_zero(probe_listener); + spa_node_add_listener(this->follower, &probe_listener, &follower_probe_events, this); + spa_hook_remove(&probe_listener); + ret = load_converter(this, info, support, n_support); spa_log_info(this->log, "%p: loaded converter %s, hnd %p, convert %p", this, this->convertname, this->hnd_convert, this->convert); diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c index 056d5eafd..99fa2a65d 100644 --- a/spa/plugins/audioconvert/audioconvert.c +++ b/spa/plugins/audioconvert/audioconvert.c @@ -1646,11 +1646,6 @@ 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); } - /* when output is convert mode, we are in OUTPUT (merge) mode, we always output all - * the incoming data to output. When output is DSP, we need to output quantum size - * chunks. */ - this->direction = this->dir[SPA_DIRECTION_OUTPUT].mode == SPA_PARAM_PORT_CONFIG_MODE_convert ? - SPA_DIRECTION_OUTPUT : SPA_DIRECTION_INPUT; this->info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS | SPA_NODE_CHANGE_MASK_PARAMS; this->info.flags &= ~SPA_NODE_FLAG_NEED_CONFIGURE; @@ -4060,6 +4055,12 @@ impl_init(const struct spa_handle_factory *factory, else if (spa_streq(k, "resample.prefill")) SPA_FLAG_UPDATE(this->resample.options, RESAMPLE_OPTION_PREFILL, spa_atob(s)); + else if (spa_streq(k, "convert.direction")) { + if (spa_streq(s, "output")) + this->direction = SPA_DIRECTION_OUTPUT; + else + this->direction = SPA_DIRECTION_INPUT; + } else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { if (s != NULL) spa_audio_parse_position(s, strlen(s), this->props.channel_map,