mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Fix mmap with multi plugin
The mmap of multi plugin seems broken (for a long time!) due to its creation of local buffer via snd_pcm_mmap(). Since the multi plugin just needs to shadow the mmap buffer of each slave, it now has mmap_shadow=1 and its own mmap/unmap method to do shadowing.
This commit is contained in:
parent
683c8bc4a2
commit
0b66de95a9
1 changed files with 34 additions and 2 deletions
|
|
@ -690,13 +690,44 @@ static snd_pcm_sframes_t snd_pcm_multi_mmap_commit(snd_pcm_t *pcm,
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_multi_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
static int snd_pcm_multi_munmap(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
|
free(pcm->mmap_channels);
|
||||||
|
free(pcm->running_areas);
|
||||||
|
pcm->mmap_channels = NULL;
|
||||||
|
pcm->running_areas = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_multi_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
static int snd_pcm_multi_mmap(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
|
snd_pcm_multi_t *multi = pcm->private_data;
|
||||||
|
unsigned int c;
|
||||||
|
|
||||||
|
pcm->mmap_channels = calloc(pcm->channels,
|
||||||
|
sizeof(pcm->mmap_channels[0]));
|
||||||
|
pcm->running_areas = calloc(pcm->channels,
|
||||||
|
sizeof(pcm->running_areas[0]));
|
||||||
|
if (!pcm->mmap_channels || !pcm->running_areas) {
|
||||||
|
snd_pcm_multi_munmap(pcm);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the slave mmapped buffer data */
|
||||||
|
for (c = 0; c < pcm->channels; c++) {
|
||||||
|
snd_pcm_multi_channel_t *chan = &multi->channels[c];
|
||||||
|
snd_pcm_t *slave;
|
||||||
|
if (chan->slave_idx < 0) {
|
||||||
|
snd_pcm_multi_munmap(pcm);
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
slave = multi->slaves[chan->slave_idx].pcm;
|
||||||
|
pcm->mmap_channels[c] =
|
||||||
|
slave->mmap_channels[chan->slave_channel];
|
||||||
|
pcm->mmap_channels[c].channel = c;
|
||||||
|
pcm->running_areas[c] =
|
||||||
|
slave->running_areas[chan->slave_channel];
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -850,6 +881,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
pcm->mmap_rw = 1;
|
pcm->mmap_rw = 1;
|
||||||
|
pcm->mmap_shadow = 1; /* has own mmap method */
|
||||||
pcm->ops = &snd_pcm_multi_ops;
|
pcm->ops = &snd_pcm_multi_ops;
|
||||||
pcm->fast_ops = &snd_pcm_multi_fast_ops;
|
pcm->fast_ops = &snd_pcm_multi_fast_ops;
|
||||||
pcm->private_data = multi;
|
pcm->private_data = multi;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue