diff --git a/spa/plugins/videoconvert/videoadapter.c b/spa/plugins/videoconvert/videoadapter.c index 57bd8391f..1bbc0f96f 100644 --- a/spa/plugins/videoconvert/videoadapter.c +++ b/spa/plugins/videoconvert/videoadapter.c @@ -114,8 +114,7 @@ static int follower_enum_params(struct impl *this, { int res; if (result->next < 0x100000) { - if (this->convert != NULL && - (res = spa_node_enum_params_sync(this->convert, + if ((res = spa_node_enum_params_sync(this->convert, id, &result->next, filter, &result->param, builder)) == 1) return res; result->next = 0x100000; @@ -176,14 +175,12 @@ static int impl_node_enum_params(void *object, int seq, next: result.index = result.next; - spa_log_debug(this->log, "%p: %d id:%u", this, seq, id); + spa_log_info(this->log, "%p: %d id:%u", this, seq, id); spa_pod_builder_reset(&b.b, &state); switch (id) { case SPA_PARAM_EnumPortConfig: - if (this->convert == NULL) - return 0; return convert_enum_port_config(this, seq, id, start, num, filter, &b.b); case SPA_PARAM_PortConfig: if (this->passthrough) { @@ -201,8 +198,6 @@ next: return 0; } } else { - if (this->convert == NULL) - return 0; return convert_enum_port_config(this, seq, id, start, num, filter, &b.b); } break; @@ -247,9 +242,6 @@ static int link_io(struct impl *this) struct spa_io_rate_match *rate_match; size_t rate_match_size; - if (this->convert == NULL) - return 0; - spa_log_debug(this->log, "%p: controls", this); spa_zero(this->io_rate_match); @@ -518,7 +510,7 @@ static int configure_format(struct impl *this, uint32_t flags, const struct spa_ format = fmt; } - if (this->convert && this->target != this->follower) { + if (this->target != this->follower) { if ((res = spa_node_port_set_param(this->convert, SPA_DIRECTION_REVERSE(this->direction), 0, SPA_PARAM_Format, flags, @@ -541,9 +533,6 @@ static int configure_convert(struct impl *this, uint32_t mode) uint8_t buffer[1024]; struct spa_pod *param; - if (this->convert == NULL) - return 0; - spa_pod_builder_init(&b, buffer, sizeof(buffer)); spa_log_debug(this->log, "%p: configure convert %p %d", this, this->target, mode); @@ -573,9 +562,6 @@ static int recalc_latency(struct impl *this, struct spa_node *src, enum spa_dire if (this->target == this->follower) return 0; - if (dst == NULL) - return 0; - while (true) { spa_pod_builder_init(&b, buffer, sizeof(buffer)); if ((res = spa_node_port_enum_params_sync(src, @@ -613,9 +599,6 @@ static int recalc_tag(struct impl *this, struct spa_node *src, enum spa_directio if (this->target == this->follower) return 0; - if (dst == NULL) - return 0; - spa_pod_dynamic_builder_init(&b, buffer, sizeof(buffer), 2048); spa_pod_builder_get_state(&b.b, &state); @@ -639,7 +622,8 @@ static int recalc_tag(struct impl *this, struct spa_node *src, enum spa_directio static int reconfigure_mode(struct impl *this, bool passthrough, - enum spa_direction direction, struct spa_pod *format) + enum spa_direction direction, enum spa_param_port_config_mode mode, + struct spa_pod *format) { int res = 0; struct spa_hook l; @@ -675,7 +659,7 @@ static int reconfigure_mode(struct impl *this, bool passthrough, spa_hook_remove(&l); } else { /* add converter ports */ - configure_convert(this, SPA_PARAM_PORT_CONFIG_MODE_dsp); + configure_convert(this, mode); } link_io(this); } @@ -756,14 +740,12 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, case SPA_PARAM_PORT_CONFIG_MODE_none: return -ENOTSUP; case SPA_PARAM_PORT_CONFIG_MODE_passthrough: - if ((res = reconfigure_mode(this, true, dir, format)) < 0) + if ((res = reconfigure_mode(this, true, dir, mode, format)) < 0) return res; break; case SPA_PARAM_PORT_CONFIG_MODE_convert: case SPA_PARAM_PORT_CONFIG_MODE_dsp: - if (this->convert == NULL) - return -ENOTSUP; - if ((res = reconfigure_mode(this, false, dir, NULL)) < 0) + if ((res = reconfigure_mode(this, false, dir, mode, NULL)) < 0) return res; break; default: @@ -894,7 +876,7 @@ static int negotiate_format(struct impl *this) } } state = 0; - if (this->convert && (res = spa_node_port_enum_params_sync(this->convert, + if ((res = spa_node_port_enum_params_sync(this->convert, SPA_DIRECTION_REVERSE(this->direction), 0, SPA_PARAM_EnumFormat, &state, format, &format, &b)) != 1) { @@ -1067,7 +1049,7 @@ static void follower_convert_port_info(void *data, this->direction == SPA_DIRECTION_INPUT ? "Input" : "Output", info, info->change_mask); - if (this->convert && info->change_mask & SPA_PORT_CHANGE_MASK_PARAMS) { + if (info->change_mask & SPA_PORT_CHANGE_MASK_PARAMS) { for (i = 0; i < info->n_params; i++) { uint32_t idx; @@ -1389,7 +1371,7 @@ static int follower_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_i int res; struct impl *this = data; - if (this->convert && this->target != this->follower) + if (this->target != this->follower) res = spa_node_port_reuse_buffer(this->convert, port_id, buffer_id); else res = spa_node_call_reuse_buffer(&this->callbacks, port_id, buffer_id); @@ -1432,11 +1414,9 @@ static int impl_node_add_listener(void *object, spa_node_add_listener(this->follower, &l, &follower_node_events, this); spa_hook_remove(&l); - if (this->convert) { - spa_zero(l); - spa_node_add_listener(this->convert, &l, &convert_node_events, this); - spa_hook_remove(&l); - } + spa_zero(l); + spa_node_add_listener(this->convert, &l, &convert_node_events, this); + spa_hook_remove(&l); this->add_listener = false; @@ -1618,7 +1598,7 @@ static int impl_node_process(void *object) * First we run the converter to process the input for the follower * then if it produced data, we run the follower. */ while (retry--) { - status = this->convert ? spa_node_process(this->convert) : 0; + status = spa_node_process(this->convert); /* schedule the follower when the converter needed * a recycled buffer */ if (status == -EPIPE || status == 0) @@ -1650,7 +1630,7 @@ static int impl_node_process(void *object) /* output node (source). First run the converter to make * sure we push out any queued data. Then when it needs * more data, schedule the follower. */ - status = this->convert ? spa_node_process(this->convert) : 0; + status = spa_node_process(this->convert); if (status == 0) status = SPA_STATUS_NEED_DATA; else if (status < 0) @@ -1714,6 +1694,30 @@ static const struct spa_node_methods impl_node = { .process = impl_node_process, }; +static int setup_convert(struct impl *this, uint32_t mode) +{ + int res; + spa_log_debug(this->log, "%p: setup converter with mode %d", this, mode); + + if ((res = configure_convert(this, mode)) >= 0) { + reconfigure_mode(this, mode == SPA_PARAM_PORT_CONFIG_MODE_none, this->direction, mode, NULL); + return 0; + } + + spa_log_warn(this->log, "%p: set mode %d on convert failed %d %s", this, + mode, res, spa_strerror(res)); + + mode = SPA_PARAM_PORT_CONFIG_MODE_none; + this->passthrough = mode == SPA_PARAM_PORT_CONFIG_MODE_none; + if ((res = configure_convert(this, mode)) < 0) { + spa_log_warn(this->log, "%p: set mode %d on convert failed %d %s", this, + mode, res, spa_strerror(res)); + return res; + } + reconfigure_mode(this, true, this->direction, mode, NULL); + return 0; +} + static int load_plugin_from(struct impl *this, const struct spa_dict *info, const char *convertname, struct spa_handle **handle, struct spa_node **iface) { @@ -1750,7 +1754,12 @@ static int load_converter(struct impl *this, const struct spa_dict *info) return ret; } } - return 0; + ret = load_plugin_from(this, info, "video.convert.dummy", &this->hnd_convert, &this->convert); + if (ret >= 0) { + this->convertname = strdup(factory_name); + return ret; + } + return -EINVAL; } static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface) @@ -1851,7 +1860,9 @@ impl_init(const struct spa_handle_factory *factory, spa_log_debug(this->log, "%p: loaded converter %s, hnd %p, convert %p", this, this->convertname, this->hnd_convert, this->convert); if (ret < 0) return ret; - this->target = this->convert; + this->target = this->direction == SPA_DIRECTION_OUTPUT + ? this->follower + : this->convert; this->info_all = SPA_NODE_CHANGE_MASK_FLAGS | SPA_NODE_CHANGE_MASK_PARAMS; @@ -1874,14 +1885,14 @@ impl_init(const struct spa_handle_factory *factory, &this->follower_listener, &follower_node_events, this); spa_node_set_callbacks(this->follower, &follower_node_callbacks, this); - // TODO: adapt port bootstrap for arbitrary converter (incl. dummy) - if (this->convert) { - spa_node_add_listener(this->convert, - &this->convert_listener, &convert_node_events, this); + spa_node_add_listener(this->convert, + &this->convert_listener, &convert_node_events, this); - configure_convert(this, SPA_PARAM_PORT_CONFIG_MODE_convert); + // TODO: adapt port bootstrap for arbitrary converter (incl. dummy) + if (this->direction == SPA_DIRECTION_OUTPUT) { + setup_convert(this, SPA_PARAM_PORT_CONFIG_MODE_none); } else { - reconfigure_mode(this, true, this->direction, NULL); + setup_convert(this, SPA_PARAM_PORT_CONFIG_MODE_convert); } link_io(this);