[alsa-devel] appl_ptr and DMA overrun at end of stream
tiwai at suse.de
Mon May 11 17:40:45 CEST 2009
At Mon, 11 May 2009 11:11:55 -0400,
Jon Smirl wrote:
> On Mon, May 11, 2009 at 9:45 AM, Jaroslav Kysela <perex at perex.cz> wrote:
> > On Mon, 11 May 2009, Jon Smirl wrote:
> >>> Right. This is the value to check in your case.
> >> What do think about redesigning the ALSA DMA interface to support
> >> detection of over and under run? Leaving the DMA engine in a loop and
> >> not coordinating with ALSA as to where the valid data is does not seem
> >> to be a safe way of exchanging data. That interface may be a source of
> >> the problems pulseaudio is encountering.
> >> A simple solution would be for snd_pcm_period_elapsed() to return
> >> physical address of the last valid sample. That would let me avoid
> >> playing with s->runtime->control->appl_ptr. You could provide the
> >> same data in the pointer() function.
> > More simpler solution is to check the stream state in the low level driver.
> > If it's in DRAINING state, then end of stream is signaled from the
> > application and driver might not queue next buffer. We may also add another
> > callback (or use ioctl callback) to pass this stream state change to the
> > lowlevel driver immediately, so the driver might react more quickly on this
> > situation.
> Quickness is the wrong way to think about this problem. ALSA knows exactly
> when it has placed valid data into the buffer.
Not really. When the mmap mode is used, the update isn't always
notified to the driver and the transfer can be completely
> It's the asynchronous nature of
> the interface that is the problem. Leaving DMA free running and counting
> on ALSA to be fast enough to keep data in front of the DMA engine is not
> a reliable mechanism.
> Wouldn't it be better to get a synchronous notification and know for sure
> what data is valid?
The question is whether you need mmap or not. If you don't need mmap,
all the transfer and the buffer update could be much more simplified
robust. But if you support mmap, appl_ptr can be updated at any time
even without the driver interaction, so the async support is
required like the current model.
> DRAINING might fix the end of stream, but what if the
> user space app gets swapped out and can't provide data fast enough?
> Most reliable for me would be to add enough info so that in my IRQ handler
> and the pointer() routine, I can check and see whether ALSA has empty/filled
> the DMA buffers and then only add them to the queue when they are full of
> valid data.
Actually, for a hardware like yours, the appl_ptr check could help
indeed. Similar implementations are found in
include/sound/pcm-direct.h. It's basically for a hardware with own
buffer to transfer, but a similar idea can be used for the DMA queue
type devices, and hopefully can be generalized in a better form...
More information about the Alsa-devel