[PATCH alsa-lib 0/4] pcm: Fix missing appl_ptr and hw_ptr updates in snd_pcm_status()
Hi,
here is the fixes for a crash with dmix plugin and co, as well as the missing appl_ptr/hw_ptr updates that are found on other plugins.
Takashi
===
Takashi Iwai (4): pcm: direct: Fix the missing appl_ptr update pcm: ioplug: Pass appl_ptr and hw_ptr in snd_pcm_status() pcm: null: Pass appl_ptr and hw_ptr in snd_pcm_status() pcm: share: Pass appl_ptr and hw_ptr in snd_pcm_status()
src/pcm/pcm_dmix.c | 1 + src/pcm/pcm_dshare.c | 1 + src/pcm/pcm_dsnoop.c | 1 + src/pcm/pcm_ioplug.c | 2 ++ src/pcm/pcm_null.c | 2 ++ src/pcm/pcm_share.c | 2 ++ 6 files changed, 9 insertions(+)
A snd_pcm_status() call for the direct plugins receives the status from the slave PCM, but this doesn't contain a valid appl_ptr, since the slave PCM for the direct plugins is in a free-wheel mode, hence the appl_ptr is always zero. This result in the inconsistent status->appl_ptr and pcm->appl.ptr, hitting the recently introduced assert() call.
Fix it by transferring the plugin's appl_ptr to the upper caller.
BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1181194 Signed-off-by: Takashi Iwai tiwai@suse.de --- src/pcm/pcm_dmix.c | 1 + src/pcm/pcm_dshare.c | 1 + src/pcm/pcm_dsnoop.c | 1 + 3 files changed, 3 insertions(+)
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index be2675aff0f3..d8495065d5d7 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -495,6 +495,7 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status) }
status->state = snd_pcm_dmix_state(pcm); + status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ status->trigger_tstamp = dmix->trigger_tstamp; status->avail = snd_pcm_mmap_playback_avail(pcm); status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max; diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c index 10243013714d..dccb137be253 100644 --- a/src/pcm/pcm_dshare.c +++ b/src/pcm/pcm_dshare.c @@ -243,6 +243,7 @@ static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status) break; } status->state = snd_pcm_dshare_state(pcm); + status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ status->trigger_tstamp = dshare->trigger_tstamp; status->avail = snd_pcm_mmap_playback_avail(pcm); status->avail_max = status->avail > dshare->avail_max ? status->avail : dshare->avail_max; diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c index c6e8cd279b53..695bf4aa340e 100644 --- a/src/pcm/pcm_dsnoop.c +++ b/src/pcm/pcm_dsnoop.c @@ -193,6 +193,7 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status) snd_pcm_status(dsnoop->spcm, status); state = snd_pcm_state(dsnoop->spcm); status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state; + status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ status->trigger_tstamp = dsnoop->trigger_tstamp; status->avail = snd_pcm_mmap_capture_avail(pcm); status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max;
The snd_pcm_status() of the ioplug doesn't return the current positions of hw_ptr and appl_ptr as advertised. Fix it by copying the current values stored in the plugin data.
Signed-off-by: Takashi Iwai tiwai@suse.de --- src/pcm/pcm_ioplug.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c index e141b1f98da7..a1463bf6b50a 100644 --- a/src/pcm/pcm_ioplug.c +++ b/src/pcm/pcm_ioplug.c @@ -133,6 +133,8 @@ static int snd_pcm_ioplug_status(snd_pcm_t *pcm, snd_pcm_status_t * status) gettimestamp(&status->tstamp, pcm->tstamp_type); status->avail = snd_pcm_mmap_avail(pcm); status->avail_max = io->avail_max; + status->appl_ptr = *pcm->appl.ptr; + status->hw_ptr = *pcm->hw.ptr; if (snd_pcm_ioplug_delay(pcm, &sd) < 0) sd = snd_pcm_mmap_delay(pcm); status->delay = sd;
Just like the previous fix for ioplug, the null plugin also misses the appl_ptr and hw_ptr updates for snd_pcm_status(). Fix it as well.
Signed-off-by: Takashi Iwai tiwai@suse.de --- src/pcm/pcm_null.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/src/pcm/pcm_null.c b/src/pcm/pcm_null.c index 1d81548569f0..c8ea9b38785f 100644 --- a/src/pcm/pcm_null.c +++ b/src/pcm/pcm_null.c @@ -96,6 +96,8 @@ static int snd_pcm_null_status(snd_pcm_t *pcm, snd_pcm_status_t * status) memset(status, 0, sizeof(*status)); status->state = null->state; status->trigger_tstamp = null->trigger_tstamp; + status->appl_ptr = *pcm->appl.ptr; + status->hw_ptr = *pcm->hw.ptr; gettimestamp(&status->tstamp, pcm->tstamp_type); status->avail = snd_pcm_null_avail_update(pcm); status->avail_max = pcm->buffer_size;
This one also has the same problem as others; the appl_ptr and hw_ptr of share plugin aren't updated in snd_pcm_status() call. Fix it.
Signed-off-by: Takashi Iwai tiwai@suse.de --- src/pcm/pcm_share.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c index bff9507d6422..72509491b366 100644 --- a/src/pcm/pcm_share.c +++ b/src/pcm/pcm_share.c @@ -711,6 +711,8 @@ static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status) _notrunning: status->delay = sd + d; status->state = share->state; + status->appl_ptr = *pcm->appl.ptr; + status->hw_ptr = *pcm->hw.ptr; status->trigger_tstamp = share->trigger_tstamp; _end: Pthread_mutex_unlock(&slave->mutex);
Dne 22. 01. 21 v 15:48 Takashi Iwai napsal(a):
Hi,
here is the fixes for a crash with dmix plugin and co, as well as the missing appl_ptr/hw_ptr updates that are found on other plugins.
It looks all correct. Dunno why it passed this in my tests. I applied all changes to alsa-lib's repo.
Thank you, Jaroslav
participants (2)
-
Jaroslav Kysela
-
Takashi Iwai