alsa: Improve format negotiation

When the device is not running but has a format, close/open the
device to get all the available formats again. Do the same when
setting a format.

Otherwise, the configuration space of the device is restricted to the
current negotiated format and we can't query the other possibilities
or change it.

Fixes #2625
This commit is contained in:
Wim Taymans 2022-08-31 10:03:39 +02:00
parent b33ffcf683
commit 2054dcf36f

View file

@ -1249,7 +1249,12 @@ spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num,
struct spa_result_node_params result;
uint32_t count = 0;
spa_log_debug(state->log, "opened:%d format:%d started:%d", state->opened,
state->have_format, state->started);
opened = state->opened;
if (!state->started && state->have_format)
spa_alsa_close(state);
if ((err = spa_alsa_open(state, NULL)) < 0)
return err;
@ -1310,6 +1315,9 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
bool match = true, planar = false, is_batch;
char spdif_params[128] = "";
spa_log_debug(state->log, "opened:%d format:%d started:%d", state->opened,
state->have_format, state->started);
state->use_mmap = !state->disable_mmap;
switch (fmt->media_subtype) {
@ -1422,6 +1430,8 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
return -EINVAL;
}
if (!state->started && state->have_format)
spa_alsa_close(state);
if ((err = spa_alsa_open(state, spdif_params)) < 0)
return err;