From 47b6c3c415fd01c9c0a639e465c4113a8c0fc81a Mon Sep 17 00:00:00 2001 From: Alexander Motzkau Date: Wed, 18 Mar 2020 22:28:05 +0100 Subject: [PATCH] pcm_a52: Determine virtual hardware pointer upon slave pointer Calculate the pointer upon the hardware pointer of the slave by querying its available frames. Thereby we can guarantee that our transfer routine will accept as many frames as the pointer indicates. BugLink: https://github.com/alsa-project/alsa-plugins/pull/8 Signed-off-by: Alexander Motzkau Signed-off-by: Jaroslav Kysela --- a52/pcm_a52.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/a52/pcm_a52.c b/a52/pcm_a52.c index b005bc2..653de12 100644 --- a/a52/pcm_a52.c +++ b/a52/pcm_a52.c @@ -325,21 +325,18 @@ static snd_pcm_sframes_t a52_transfer(snd_pcm_ioplug_t *io, /* * pointer callback * - * Calculate the current position from the delay of slave PCM + * Calculate the current position from the available frames of slave PCM */ static snd_pcm_sframes_t a52_pointer(snd_pcm_ioplug_t *io) { struct a52_ctx *rec = io->private_data; - snd_pcm_sframes_t delay; + snd_pcm_sframes_t avail; snd_pcm_state_t state; - int err; state = snd_pcm_state(rec->slave); switch (state) { case SND_PCM_STATE_RUNNING: case SND_PCM_STATE_DRAINING: - if ((err = snd_pcm_delay(rec->slave, &delay)) < 0) - return err; break; case SND_PCM_STATE_XRUN: case SND_PCM_STATE_SUSPENDED: @@ -348,16 +345,25 @@ static snd_pcm_sframes_t a52_pointer(snd_pcm_ioplug_t *io) return 0; } - if (delay < 0 || delay >= (snd_pcm_sframes_t)rec->slave_buffer_size) - delay = 0; - delay = (snd_pcm_sframes_t)io->appl_ptr - delay; - if (delay < 0) { - delay += io->buffer_size; - if (delay < 0) - delay = 0; + avail = 0; + + /* Write what we have from outbuf. */ + write_out_pending(io, rec); + + /* If there is anything remaining in outbuf, we can't + * accept any full packets. */ + if (rec->remain == 0) + { + /* Round the slave frames to multiples of the packet size. */ + avail += (snd_pcm_avail_update(rec->slave) / rec->avctx->frame_size) * rec->avctx->frame_size; } - delay %= io->buffer_size; - return delay; + + if (avail < 0) + avail = 0; + else if (avail >= io->buffer_size) + avail = io->buffer_size - 1; + + return (io->appl_ptr + avail) % io->buffer_size; } /* set up the fixed parameters of slave PCM hw_parmas */ -- 2.47.1