diff --git a/spa/plugins/alsa/alsa-pcm-sink.c b/spa/plugins/alsa/alsa-pcm-sink.c index b26554b68..6387ae17a 100644 --- a/spa/plugins/alsa/alsa-pcm-sink.c +++ b/spa/plugins/alsa/alsa-pcm-sink.c @@ -616,7 +616,7 @@ static int port_set_format(void *object, const struct spa_pod *format) { struct state *this = object; - int err; + int err = 0; if (format == NULL) { if (!this->have_format) @@ -673,7 +673,7 @@ static int port_set_format(void *object, } emit_port_info(this, false); - return 0; + return err; } static int diff --git a/spa/plugins/alsa/alsa-pcm-source.c b/spa/plugins/alsa/alsa-pcm-source.c index c4222dc89..c50a4dea7 100644 --- a/spa/plugins/alsa/alsa-pcm-source.c +++ b/spa/plugins/alsa/alsa-pcm-source.c @@ -566,7 +566,7 @@ static int port_set_format(void *object, uint32_t flags, const struct spa_pod *format) { struct state *this = object; - int err; + int err = 0; if (format == NULL) { if (!this->have_format) @@ -610,7 +610,7 @@ static int port_set_format(void *object, } emit_port_info(this, false); - return 0; + return err; } static int diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c index de321ee3c..19c2c0a0e 100644 --- a/spa/plugins/alsa/alsa-pcm.c +++ b/spa/plugins/alsa/alsa-pcm.c @@ -1409,7 +1409,10 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_ state->props.device, rchannels, val); if (!SPA_FLAG_IS_SET(flags, SPA_NODE_PARAM_FLAG_NEAREST)) return -EINVAL; + if (fmt->media_subtype != SPA_MEDIA_SUBTYPE_raw) + return -EINVAL; rchannels = val; + fmt->info.raw.channels = rchannels; match = false; } @@ -1429,7 +1432,10 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_ state->props.device, rrate, val); if (!SPA_FLAG_IS_SET(flags, SPA_NODE_PARAM_FLAG_NEAREST)) return -EINVAL; + if (fmt->media_subtype != SPA_MEDIA_SUBTYPE_raw) + return -EINVAL; rrate = val; + fmt->info.raw.rate = rrate; match = false; } diff --git a/spa/plugins/audioconvert/audioadapter.c b/spa/plugins/audioconvert/audioadapter.c index 19b1e1cc5..cfb8163bc 100644 --- a/spa/plugins/audioconvert/audioadapter.c +++ b/spa/plugins/audioconvert/audioadapter.c @@ -442,6 +442,29 @@ static int configure_format(struct impl *this, uint32_t flags, const struct spa_ if (format && spa_log_level_enabled(this->log, SPA_LOG_LEVEL_DEBUG)) spa_debug_format(0, NULL, format); + if ((res = spa_node_port_set_param(this->follower, + this->direction, 0, + SPA_PARAM_Format, flags, + format)) < 0) + return res; + if (res > 0) { + uint8_t buffer[4096]; + struct spa_pod_builder b = { 0 }; + uint32_t state = 0; + struct spa_pod *fmt; + + /* format was changed to nearest compatible format */ + spa_pod_builder_init(&b, buffer, sizeof(buffer)); + + if ((res = spa_node_port_enum_params_sync(this->follower, + this->direction, 0, + SPA_PARAM_Format, &state, + NULL, &fmt, &b)) != 1) + return -EIO; + + format = fmt; + } + if (this->target != this->follower && this->convert) { if ((res = spa_node_port_set_param(this->convert, SPA_DIRECTION_REVERSE(this->direction), 0, @@ -450,12 +473,6 @@ static int configure_format(struct impl *this, uint32_t flags, const struct spa_ return res; } - if ((res = spa_node_port_set_param(this->follower, - this->direction, 0, - SPA_PARAM_Format, flags, - format)) < 0) - return res; - this->have_format = format != NULL; if (format == NULL) { this->n_buffers = 0; @@ -513,7 +530,7 @@ static int reconfigure_mode(struct impl *this, bool passthrough, /* set new target */ this->target = passthrough ? this->follower : this->convert; - if ((res = configure_format(this, 0, format)) < 0) + if ((res = configure_format(this, SPA_NODE_PARAM_FLAG_NEAREST, format)) < 0) return res; if (this->passthrough != passthrough) { @@ -775,7 +792,7 @@ static int negotiate_format(struct impl *this) spa_pod_fixate(format); - res = configure_format(this, 0, format); + res = configure_format(this, SPA_NODE_PARAM_FLAG_NEAREST, format); done: spa_node_send_command(this->follower,