mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
fix infinite draining of the rate plugin in SND_PCM_NONBLOCK mode
The draining function of the rate plugin does not handle properly the SND_PCM_NONBLOCK case. It can write data to the slave plugin each time the function is called, but does not update its internal state in order to reach a stopping condition. Use a last_commit_ptr workaround to reach such condition. Signed-off-by: Sylvain BERTRAND <sylvain.bertrand@legeek.net> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
496e239e65
commit
29041c5220
1 changed files with 17 additions and 1 deletions
|
|
@ -1051,6 +1051,7 @@ static int snd_pcm_rate_drain(snd_pcm_t *pcm)
|
||||||
/* commit the remaining fraction (if any) */
|
/* commit the remaining fraction (if any) */
|
||||||
snd_pcm_uframes_t size, ofs, saved_avail_min;
|
snd_pcm_uframes_t size, ofs, saved_avail_min;
|
||||||
snd_pcm_sw_params_t sw_params;
|
snd_pcm_sw_params_t sw_params;
|
||||||
|
int commit_err;
|
||||||
|
|
||||||
__snd_pcm_lock(pcm);
|
__snd_pcm_lock(pcm);
|
||||||
/* temporarily set avail_min to one */
|
/* temporarily set avail_min to one */
|
||||||
|
|
@ -1079,14 +1080,29 @@ static int snd_pcm_rate_drain(snd_pcm_t *pcm)
|
||||||
if (! spsize)
|
if (! spsize)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
snd_pcm_rate_commit_area(pcm, rate, ofs,
|
commit_err = snd_pcm_rate_commit_area(pcm, rate, ofs,
|
||||||
psize, spsize);
|
psize, spsize);
|
||||||
|
if (commit_err == 1) {
|
||||||
|
rate->last_commit_ptr += psize;
|
||||||
|
if (rate->last_commit_ptr >= pcm->boundary)
|
||||||
|
rate->last_commit_ptr = 0;
|
||||||
|
} else if (commit_err == 0) {
|
||||||
|
if (pcm->mode & SND_PCM_NONBLOCK != 0) {
|
||||||
|
commit_err = -EAGAIN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
ofs = (ofs + psize) % pcm->buffer_size;
|
ofs = (ofs + psize) % pcm->buffer_size;
|
||||||
size -= psize;
|
size -= psize;
|
||||||
}
|
}
|
||||||
sw_params.avail_min = saved_avail_min;
|
sw_params.avail_min = saved_avail_min;
|
||||||
snd_pcm_sw_params(rate->gen.slave, &sw_params);
|
snd_pcm_sw_params(rate->gen.slave, &sw_params);
|
||||||
__snd_pcm_unlock(pcm);
|
__snd_pcm_unlock(pcm);
|
||||||
|
if (commit_err < 0)
|
||||||
|
return commit_err;
|
||||||
}
|
}
|
||||||
return snd_pcm_drain(rate->gen.slave);
|
return snd_pcm_drain(rate->gen.slave);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue