audioadapter: clear rate matching when not using converter

Ensure that we clear the rate matching when we are not using the
converter. This will make the follower use the quantum instead of the
dummy unused rate matching area.

Exit when we can't make an internal converter because then things really
are not going to work. Remove some of the pointless NULL checks.
This commit is contained in:
Wim Taymans 2023-03-30 11:47:25 +02:00
parent a163f29a43
commit 4fb17d1c03

View file

@ -227,30 +227,40 @@ next:
static int link_io(struct impl *this) static int link_io(struct impl *this)
{ {
int res; int res;
struct spa_io_rate_match *rate_match;
if (this->convert == NULL) size_t rate_match_size;
return 0;
spa_log_debug(this->log, "%p: controls", this); spa_log_debug(this->log, "%p: controls", this);
spa_zero(this->io_rate_match); spa_zero(this->io_rate_match);
this->io_rate_match.rate = 1.0; this->io_rate_match.rate = 1.0;
if (this->follower == this->target) {
rate_match = NULL;
rate_match_size = 0;
} else {
rate_match = &this->io_rate_match;
rate_match_size = sizeof(this->io_rate_match);
}
if ((res = spa_node_port_set_io(this->follower, if ((res = spa_node_port_set_io(this->follower,
this->direction, 0, this->direction, 0,
SPA_IO_RateMatch, SPA_IO_RateMatch,
&this->io_rate_match, sizeof(this->io_rate_match))) < 0) { rate_match, rate_match_size)) < 0) {
spa_log_debug(this->log, "%p: set RateMatch on follower disabled %d %s", this, spa_log_debug(this->log, "%p: set RateMatch on follower disabled %d %s", this,
res, spa_strerror(res)); res, spa_strerror(res));
} }
else if ((res = spa_node_port_set_io(this->convert, else if ((res = spa_node_port_set_io(this->convert,
SPA_DIRECTION_REVERSE(this->direction), 0, SPA_DIRECTION_REVERSE(this->direction), 0,
SPA_IO_RateMatch, SPA_IO_RateMatch,
&this->io_rate_match, sizeof(this->io_rate_match))) < 0) { rate_match, rate_match_size)) < 0) {
spa_log_warn(this->log, "%p: set RateMatch on convert failed %d %s", this, spa_log_warn(this->log, "%p: set RateMatch on convert failed %d %s", this,
res, spa_strerror(res)); res, spa_strerror(res));
} }
if (this->follower == this->target)
return 0;
this->io_buffers = SPA_IO_BUFFERS_INIT; this->io_buffers = SPA_IO_BUFFERS_INIT;
if ((res = spa_node_port_set_io(this->follower, if ((res = spa_node_port_set_io(this->follower,
@ -488,7 +498,7 @@ static int configure_format(struct impl *this, uint32_t flags, const struct spa_
format = fmt; format = fmt;
} }
if (this->target != this->follower && this->convert) { if (this->target != this->follower) {
if ((res = spa_node_port_set_param(this->convert, if ((res = spa_node_port_set_param(this->convert,
SPA_DIRECTION_REVERSE(this->direction), 0, SPA_DIRECTION_REVERSE(this->direction), 0,
SPA_PARAM_Format, flags, SPA_PARAM_Format, flags,
@ -566,8 +576,8 @@ static int reconfigure_mode(struct impl *this, bool passthrough,
} else { } else {
/* add converter ports */ /* add converter ports */
configure_convert(this, SPA_PARAM_PORT_CONFIG_MODE_dsp); configure_convert(this, SPA_PARAM_PORT_CONFIG_MODE_dsp);
link_io(this);
} }
link_io(this);
} }
this->info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS | SPA_NODE_CHANGE_MASK_PARAMS; this->info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS | SPA_NODE_CHANGE_MASK_PARAMS;
@ -775,18 +785,16 @@ static int negotiate_format(struct impl *this)
goto done; goto done;
} }
} }
if (this->convert) { state = 0;
state = 0; if ((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_DIRECTION_REVERSE(this->direction), 0, SPA_PARAM_EnumFormat, &state,
SPA_PARAM_EnumFormat, &state, format, &format, &b)) != 1) {
format, &format, &b)) != 1) { debug_params(this, this->convert,
debug_params(this, this->convert, SPA_DIRECTION_REVERSE(this->direction), 0,
SPA_DIRECTION_REVERSE(this->direction), 0, SPA_PARAM_EnumFormat, format, "convert format", res);
SPA_PARAM_EnumFormat, format, "convert format", res); res = -ENOTSUP;
res = -ENOTSUP; goto done;
goto done;
}
} }
if (format == NULL) { if (format == NULL) {
res = -ENOTSUP; res = -ENOTSUP;
@ -1230,7 +1238,7 @@ static int follower_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_i
int res; int res;
struct impl *this = data; struct impl *this = data;
if (this->target != this->follower && this->convert) if (this->target != this->follower)
res = spa_node_port_reuse_buffer(this->convert, port_id, buffer_id); res = spa_node_port_reuse_buffer(this->convert, port_id, buffer_id);
else else
res = spa_node_call_reuse_buffer(&this->callbacks, port_id, buffer_id); res = spa_node_call_reuse_buffer(&this->callbacks, port_id, buffer_id);
@ -1273,11 +1281,10 @@ static int impl_node_add_listener(void *object,
spa_node_add_listener(this->follower, &l, &follower_node_events, this); spa_node_add_listener(this->follower, &l, &follower_node_events, this);
spa_hook_remove(&l); spa_hook_remove(&l);
if (this->convert) { spa_zero(l);
spa_zero(l); spa_node_add_listener(this->convert, &l, &convert_node_events, this);
spa_node_add_listener(this->convert, &l, &convert_node_events, this); spa_hook_remove(&l);
spa_hook_remove(&l);
}
this->add_listener = false; this->add_listener = false;
emit_node_info(this, true); emit_node_info(this, true);
@ -1467,7 +1474,7 @@ static int impl_node_process(void *object)
* First we run the converter to process the input for the follower * First we run the converter to process the input for the follower
* then if it produced data, we run the follower. */ * then if it produced data, we run the follower. */
while (retry--) { while (retry--) {
status = this->convert ? spa_node_process(this->convert) : 0; status = spa_node_process(this->convert);
/* schedule the follower when the converter needed /* schedule the follower when the converter needed
* a recycled buffer */ * a recycled buffer */
if (status == -EPIPE || status == 0) if (status == -EPIPE || status == 0)
@ -1499,7 +1506,7 @@ static int impl_node_process(void *object)
/* output node (source). First run the converter to make /* output node (source). First run the converter to make
* sure we push out any queued data. Then when it needs * sure we push out any queued data. Then when it needs
* more data, schedule the follower. */ * more data, schedule the follower. */
status = this->convert ? spa_node_process(this->convert) : 0; status = spa_node_process(this->convert);
if (status == 0) if (status == 0)
status = SPA_STATUS_NEED_DATA; status = SPA_STATUS_NEED_DATA;
else if (status < 0) else if (status < 0)
@ -1661,6 +1668,9 @@ impl_init(const struct spa_handle_factory *factory,
info, support, n_support); info, support, n_support);
spa_handle_get_interface(this->hnd_convert, SPA_TYPE_INTERFACE_Node, &iface); spa_handle_get_interface(this->hnd_convert, SPA_TYPE_INTERFACE_Node, &iface);
if (iface == NULL)
return -EINVAL;
this->convert = iface; this->convert = iface;
this->target = this->convert; this->target = this->convert;