Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

snd_pcm_drain() infinite loop #41

Closed
sylware opened this issue Apr 11, 2020 · 10 comments
Closed

snd_pcm_drain() infinite loop #41

sylware opened this issue Apr 11, 2020 · 10 comments

Comments

@sylware
Copy link
Contributor

sylware commented Apr 11, 2020

In a non-blocking dmix-ed plugin pipeline (see below), playing audio from a 44100Hz source to a running 48000Hz hardware pcm, will go into an -EAGAIN infinite loop in snd_pcm_drain().
I did a bit of tracing and it seems snd_pcm_drain() will always return -EAGAIN because in pcm_dmix.c:snd_pcm_dmix_sync_ptr0, avail is never >= pcm->stop_threshold

@sylware
Copy link
Contributor Author

sylware commented Apr 12, 2020

ALSA:HW_PARAMS START------------------------------------------------------------
ACCESS: RW_NONINTERLEAVED
FORMAT: FLOAT_LE
SUBFORMAT: STD
SAMPLE_BITS: [0 0]
FRAME_BITS: [64 64]
CHANNELS: [2 2]
RATE: [44100 44100]
PERIOD_TIME: [21333 21333]
PERIOD_SIZE: [940 940]
PERIOD_BYTES: [0 0]
PERIODS: [0 0]
BUFFER_TIME: [0 0]
BUFFER_SIZE: [7526 7526]
BUFFER_BYTES: [60208 60208]
TICK_TIME: [0 0]
ALSA:HW_PARAMS END--------------------------------------------------------------
ALSA:SW_PARAMS START------------------------------------------------------------
tstamp_mode: NONE
tstamp_type: MONOTONIC_RAW
period_step: 1
avail_min: 940
start_threshold: 1
stop_threshold: 7526
silence_threshold: 0
silence_size: 0
boundary: 4236761349448794112
ALSA:SW_PARAMS END--------------------------------------------------------------
ALSA PCM DUMP START-------------------------------------------------------------
Plug PCM: Linear Integer <-> Linear Float conversion PCM (S32_LE)
Its setup is:
stream : PLAYBACK
access : RW_NONINTERLEAVED
format : FLOAT_LE
subformat : STD
channels : 2
rate : 44100
exact rate : 44100 (44100/1)
msbits : 32
buffer_size : 7526
period_size : 940
period_time : 21333
tstamp_mode : NONE
tstamp_type : MONOTONIC_RAW
period_step : 1
avail_min : 940
period_event : 1
start_threshold : 1
stop_threshold : 7526
silence_threshold: 0
silence_size : 0
boundary : 4236761349448794112
Slave: Rate conversion PCM (48000, sformat=S32_LE)
Converter: linear-interpolation
Protocol version: 10002
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : S32_LE
subformat : STD
channels : 2
rate : 44100
exact rate : 44100 (44100/1)
msbits : 32
buffer_size : 7526
period_size : 940
period_time : 21333
tstamp_mode : NONE
tstamp_type : MONOTONIC_RAW
period_step : 1
avail_min : 940
period_event : 1
start_threshold : 1
stop_threshold : 7526
silence_threshold: 0
silence_size : 0
boundary : 4236761349448794112
Slave: Soft volume PCM
Control: PCM Playback Volume
min_dB: -51
max_dB: 0
resolution: 256
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : S32_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (48000/1)
msbits : 32
buffer_size : 8192
period_size : 1024
period_time : 21333
tstamp_mode : NONE
tstamp_type : MONOTONIC_RAW
period_step : 1
avail_min : 1024
period_event : 1
start_threshold : 1
stop_threshold : 8192
silence_threshold: 0
silence_size : 0
boundary : 4611686018427387904
Slave: Direct Stream Mixing PCM
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : S32_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (48000/1)
msbits : 32
buffer_size : 8192
period_size : 1024
period_time : 21333
tstamp_mode : NONE
tstamp_type : MONOTONIC_RAW
period_step : 1
avail_min : 1024
period_event : 1
start_threshold : 1
stop_threshold : 8192
silence_threshold: 0
silence_size : 0
boundary : 4611686018427387904
Hardware PCM card 0 'HDA ATI SB' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : S32_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (48000/1)
msbits

@sylware
Copy link
Contributor Author

sylware commented Apr 12, 2020

in the function pcm_rate.c:snd_pcm_rate_drain, the while loop which is supposed to write the remaining audio data to the slave using snd_pcm_rate_commit_area function, does not seem to update rate->last_commit_ptr, which is then "stuck", hence the never ending writting of data to the slave.

@sylware
Copy link
Contributor Author

sylware commented Apr 12, 2020

I wrote a quick and dirty patch which updates last_commit_ptr: it seems it fixes the issues.
That said I have no idea how to update properly this pointer in regards of boundary (and maybe other critical values).

@perexg
Copy link
Member

perexg commented Apr 17, 2020

The drain is not supposed to update last_commit_ptr. Also, unless the drain is not called multiple times, the while loop takes last_commit_ptr only once. Do you call drain in the non-block mode?

@sylware
Copy link
Contributor Author

sylware commented Apr 19, 2020 via email

@sylware
Copy link
Contributor Author

sylware commented Apr 23, 2020 via email

@perexg
Copy link
Member

perexg commented Apr 23, 2020

https://mailman.alsa-project.org/pipermail/alsa-devel/2020-April/165848.html

The patch looks basically good (we can fix it later if we encounter any issues). Create PR or resend with proper description and signed-off-by line. Thanks.

@sylware
Copy link
Contributor Author

sylware commented Apr 24, 2020 via email

@sylware
Copy link
Contributor Author

sylware commented Apr 30, 2020

Could not break it in my usage. I posted the patch on the mailing-list.
I hope I kept the state consistent enough for the draining to reach the end in intended use cases.

@perexg
Copy link
Member

perexg commented Apr 30, 2020

Applied in 29041c5 . Thank you.

@perexg perexg closed this as completed Apr 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants