module-ffado: only start after ports are configured

Don't start yet when the ports are pending configuration.

See #3968
This commit is contained in:
Wim Taymans 2024-04-22 17:43:04 +02:00
parent 64695a8611
commit 0e13d088e7

View file

@ -190,6 +190,7 @@ struct stream {
struct port *ports[MAX_PORTS];
struct volume volume;
unsigned int ready:1;
unsigned int running:1;
};
@ -288,7 +289,8 @@ static inline void do_volume(float *dst, const float *src, struct volume *vol, u
static void clear_port_buffer(struct port *p, uint32_t n_samples)
{
if (!p->cleared) {
memset(p->buffer, 0, n_samples * sizeof(uint32_t));
if (p->buffer)
memset(p->buffer, 0, n_samples * sizeof(uint32_t));
p->cleared = true;
}
}
@ -527,9 +529,17 @@ static void stream_destroy(void *d)
s->n_ports = 0;
spa_hook_remove(&s->listener);
s->filter = NULL;
s->ready = false;
s->running = false;
}
static void check_start(struct impl *impl)
{
if ((!(impl->mode & MODE_SINK) || (impl->sink.ready && impl->sink.running)) &&
(!(impl->mode & MODE_SOURCE) || (impl->source.ready && impl->source.running)))
start_ffado_device(impl);
}
static void stream_state_changed(void *d, enum pw_filter_state old,
enum pw_filter_state state, const char *error)
{
@ -548,8 +558,8 @@ static void stream_state_changed(void *d, enum pw_filter_state old,
stop_ffado_device(impl);
break;
case PW_FILTER_STATE_STREAMING:
if (start_ffado_device(impl) >= 0)
s->running = true;
s->running = true;
check_start(impl);
break;
default:
break;
@ -678,7 +688,7 @@ static void param_latency_changed(struct stream *s, const struct spa_pod *param,
}
}
static void make_stream_ports(struct stream *s)
static int make_stream_ports(struct stream *s)
{
struct impl *impl = s->impl;
struct pw_properties *props;
@ -748,7 +758,7 @@ static void make_stream_ports(struct stream *s)
sizeof(struct port_data), props, params, n_params);
if (port->data == NULL) {
pw_log_error("Can't create port: %m");
return;
return -errno;
}
port->data->port = port;
@ -757,9 +767,10 @@ static void make_stream_ports(struct stream *s)
port->buffer = calloc(impl->quantum_limit, sizeof(float));
if (port->buffer == NULL) {
pw_log_error("Can't create port buffer: %m");
return;
return -errno;
}
}
return 0;
}
static void setup_stream_ports(struct stream *s)
@ -836,6 +847,7 @@ static void stream_param_changed(void *data, void *port_data, uint32_t id,
const struct spa_pod *param)
{
struct stream *s = data;
if (port_data != NULL) {
switch (id) {
case SPA_PARAM_Latency:
@ -846,7 +858,10 @@ static void stream_param_changed(void *data, void *port_data, uint32_t id,
switch (id) {
case SPA_PARAM_PortConfig:
pw_log_debug("PortConfig");
make_stream_ports(s);
if (make_stream_ports(s) >= 0) {
s->ready = true;
check_start(s->impl);
}
break;
case SPA_PARAM_Props:
pw_log_debug("Props");
@ -954,8 +969,8 @@ again:
pw_log_error("FFADO error");
return;
}
source_running = impl->source.running;
sink_running = impl->sink.running;
source_running = impl->source.running && impl->sink.ready;
sink_running = impl->sink.running && impl->source.ready;
if (!source_running)
ffado_streaming_transfer_capture_buffers(impl->dev);