mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa: handle the case where the driver is destroyed
When the driver node is destroyed (like when unplugging the cable) it will drop/pause all of the follower ALSA nodes. This is something that happens internally because of how the ALSA nodes work together, on the PipeWire level, the nodes are still running and they will just be moved to another driver. The problem is that nothing will then start the nodes again after moving it to the new driver. Fix this by keeping track of the desired target state of the ALSA node and restoring that state when we detect that we are paused when moved to a new driver. Fixes #4401
This commit is contained in:
parent
3b51dbba1c
commit
1084cc24b6
4 changed files with 8 additions and 2 deletions
|
|
@ -326,11 +326,13 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
|
|||
if (this->n_buffers == 0)
|
||||
return -EIO;
|
||||
|
||||
this->want_started = true;
|
||||
if ((res = spa_alsa_start(this)) < 0)
|
||||
return res;
|
||||
break;
|
||||
case SPA_NODE_COMMAND_Suspend:
|
||||
case SPA_NODE_COMMAND_Pause:
|
||||
this->want_started = false;
|
||||
if ((res = spa_alsa_pause(this)) < 0)
|
||||
return res;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -292,11 +292,13 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
|
|||
if (this->n_buffers == 0)
|
||||
return -EIO;
|
||||
|
||||
this->want_started = true;
|
||||
if ((res = spa_alsa_start(this)) < 0)
|
||||
return res;
|
||||
break;
|
||||
case SPA_NODE_COMMAND_Pause:
|
||||
case SPA_NODE_COMMAND_Suspend:
|
||||
this->want_started = false;
|
||||
if ((res = spa_alsa_pause(this)) < 0)
|
||||
return res;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -3575,9 +3575,8 @@ static int do_state_sync(struct spa_loop *loop, bool async, uint32_t seq,
|
|||
rt->driver = state->driver;
|
||||
spa_log_debug(state->log, "state:%p -> driver:%p", state, state->driver);
|
||||
|
||||
if(state->linked && state->matching) {
|
||||
if(state->linked && state->matching)
|
||||
try_unlink(state);
|
||||
}
|
||||
}
|
||||
if (state->following) {
|
||||
remove_sources(state);
|
||||
|
|
@ -3749,6 +3748,8 @@ int spa_alsa_reassign_follower(struct state *state)
|
|||
setup_matching(state);
|
||||
if (state->started)
|
||||
spa_loop_invoke(state->data_loop, do_state_sync, 0, NULL, 0, true, state);
|
||||
else if (state->want_started)
|
||||
spa_alsa_start(state);
|
||||
|
||||
freewheel = pos != NULL && SPA_FLAG_IS_SET(pos->clock.flags, SPA_IO_CLOCK_FLAG_FREEWHEEL);
|
||||
if (state->freewheel != freewheel) {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ struct state {
|
|||
unsigned int opened:1;
|
||||
unsigned int prepared:1;
|
||||
unsigned int started:1;
|
||||
unsigned int want_started:1;
|
||||
snd_pcm_t *hndl;
|
||||
|
||||
bool have_format;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue