mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
Fix possible problems of playback drain with rate plugin
Fixed the possible problems of playback drain with rate plugin when partial data remains and not committed before.
This commit is contained in:
parent
da34d7ec96
commit
3047f8fa5a
1 changed files with 38 additions and 10 deletions
|
|
@ -978,9 +978,11 @@ static int snd_pcm_rate_poll_ask(snd_pcm_t *pcm)
|
|||
return snd_pcm_sw_params(rate->gen.slave, &rate->sw_params);
|
||||
}
|
||||
|
||||
static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t appl_offset)
|
||||
static int snd_pcm_rate_commit_area(snd_pcm_t *pcm, snd_pcm_rate_t *rate,
|
||||
snd_pcm_uframes_t appl_offset,
|
||||
snd_pcm_uframes_t size,
|
||||
snd_pcm_uframes_t slave_size)
|
||||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
snd_pcm_uframes_t cont = pcm->buffer_size - appl_offset;
|
||||
const snd_pcm_channel_area_t *areas;
|
||||
const snd_pcm_channel_area_t *slave_areas;
|
||||
|
|
@ -989,18 +991,18 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app
|
|||
snd_pcm_sframes_t result;
|
||||
|
||||
areas = snd_pcm_mmap_areas(pcm);
|
||||
if (cont >= pcm->period_size) {
|
||||
if (cont >= size) {
|
||||
result = snd_pcm_mmap_begin(rate->gen.slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
if (result < 0)
|
||||
return result;
|
||||
if (slave_frames < rate->gen.slave->period_size) {
|
||||
if (slave_frames < slave_size) {
|
||||
snd_pcm_rate_write_areas1(pcm, areas, appl_offset, rate->sareas, 0);
|
||||
goto __partial;
|
||||
}
|
||||
snd_pcm_rate_write_areas1(pcm, areas, appl_offset,
|
||||
slave_areas, slave_offset);
|
||||
result = snd_pcm_mmap_commit(rate->gen.slave, slave_offset, rate->gen.slave->period_size);
|
||||
if (result < (snd_pcm_sframes_t)rate->gen.slave->period_size) {
|
||||
result = snd_pcm_mmap_commit(rate->gen.slave, slave_offset, slave_size);
|
||||
if (result < (snd_pcm_sframes_t)slave_size) {
|
||||
if (result < 0)
|
||||
return result;
|
||||
result = snd_pcm_rewind(rate->gen.slave, result);
|
||||
|
|
@ -1015,7 +1017,7 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app
|
|||
pcm->format);
|
||||
snd_pcm_areas_copy(rate->pareas, cont,
|
||||
areas, 0,
|
||||
pcm->channels, pcm->period_size - cont,
|
||||
pcm->channels, size - cont,
|
||||
pcm->format);
|
||||
|
||||
snd_pcm_rate_write_areas1(pcm, rate->pareas, 0, rate->sareas, 0);
|
||||
|
|
@ -1027,8 +1029,8 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app
|
|||
__partial:
|
||||
xfer = 0;
|
||||
cont = rate->gen.slave->buffer_size - slave_offset;
|
||||
if (cont > rate->gen.slave->period_size)
|
||||
cont = rate->gen.slave->period_size;
|
||||
if (cont > slave_size)
|
||||
cont = slave_size;
|
||||
snd_pcm_areas_copy(slave_areas, slave_offset,
|
||||
rate->sareas, 0,
|
||||
pcm->channels, cont,
|
||||
|
|
@ -1074,6 +1076,14 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t appl_offset)
|
||||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
|
||||
return snd_pcm_rate_commit_area(pcm, rate, appl_offset, pcm->period_size,
|
||||
rate->gen.slave->period_size);
|
||||
}
|
||||
|
||||
static int snd_pcm_rate_grab_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t hw_offset)
|
||||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
|
|
@ -1266,6 +1276,24 @@ static snd_pcm_sframes_t snd_pcm_rate_avail_update(snd_pcm_t *pcm)
|
|||
}
|
||||
}
|
||||
|
||||
static int snd_pcm_rate_drain(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
|
||||
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
|
||||
/* commit the remaining fraction (if any) */
|
||||
snd_pcm_uframes_t size, slave_size;
|
||||
size = rate->appl_ptr - rate->last_commit_ptr;
|
||||
if (size > 0) {
|
||||
slave_size = snd_pcm_rate_slave_frames(pcm, size);
|
||||
if (slave_size > 0)
|
||||
snd_pcm_rate_commit_area(pcm, rate, rate->last_commit_ptr % pcm->buffer_size,
|
||||
size, slave_size);
|
||||
}
|
||||
}
|
||||
return snd_pcm_drain(rate->gen.slave);
|
||||
}
|
||||
|
||||
static int snd_pcm_rate_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
|
||||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
|
|
@ -1324,7 +1352,7 @@ static snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = {
|
|||
.reset = snd_pcm_rate_reset,
|
||||
.start = snd_pcm_generic_start,
|
||||
.drop = snd_pcm_generic_drop,
|
||||
.drain = snd_pcm_generic_drain,
|
||||
.drain = snd_pcm_rate_drain,
|
||||
.pause = snd_pcm_generic_pause,
|
||||
.rewind = snd_pcm_rate_rewind,
|
||||
.forward = snd_pcm_rate_forward,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue