mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
Fixed file plugin - mmap access was broken and revents were not handled correctly
This commit is contained in:
parent
37728639ae
commit
131d6610fc
5 changed files with 50 additions and 19 deletions
|
|
@ -2257,6 +2257,8 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t
|
||||||
char *dst;
|
char *dst;
|
||||||
int width;
|
int width;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
|
if (dst_area == src_area && dst_offset == src_offset)
|
||||||
|
return 0;
|
||||||
if (!src_area->addr)
|
if (!src_area->addr)
|
||||||
return snd_pcm_area_silence(dst_area, dst_offset, samples, format);
|
return snd_pcm_area_silence(dst_area, dst_offset, samples, format);
|
||||||
src = snd_pcm_channel_area_addr(src_area, src_offset);
|
src = snd_pcm_channel_area_addr(src_area, src_offset);
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,12 @@ static int snd_pcm_file_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
return snd_pcm_async(file->slave, sig, pid);
|
return snd_pcm_async(file->slave, sig, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_pcm_file_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||||
|
{
|
||||||
|
snd_pcm_file_t *file = pcm->private_data;
|
||||||
|
return snd_pcm_poll_descriptors_revents(file->slave, pfds, nfds, revents);
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
static int snd_pcm_file_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private_data;
|
snd_pcm_file_t *file = pcm->private_data;
|
||||||
|
|
@ -345,6 +351,19 @@ static int snd_pcm_file_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||||
return snd_pcm_hw_refine(file->slave, params);
|
return snd_pcm_hw_refine(file->slave, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
|
||||||
|
{
|
||||||
|
snd_pcm_file_t *file = pcm->private_data;
|
||||||
|
if (file->wbuf) {
|
||||||
|
free(file->wbuf);
|
||||||
|
if (file->wbuf_areas)
|
||||||
|
free(file->wbuf_areas);
|
||||||
|
file->wbuf = 0;
|
||||||
|
file->wbuf_areas = 0;
|
||||||
|
}
|
||||||
|
return snd_pcm_hw_free(file->slave);
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private_data;
|
snd_pcm_file_t *file = pcm->private_data;
|
||||||
|
|
@ -358,7 +377,15 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
||||||
file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size);
|
file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size);
|
||||||
assert(!file->wbuf);
|
assert(!file->wbuf);
|
||||||
file->wbuf = malloc(file->wbuf_size_bytes);
|
file->wbuf = malloc(file->wbuf_size_bytes);
|
||||||
|
if (file->wbuf == NULL) {
|
||||||
|
snd_pcm_file_hw_free(pcm);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
file->wbuf_areas = malloc(sizeof(*file->wbuf_areas) * slave->channels);
|
file->wbuf_areas = malloc(sizeof(*file->wbuf_areas) * slave->channels);
|
||||||
|
if (file->wbuf_areas == NULL) {
|
||||||
|
snd_pcm_file_hw_free(pcm);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
file->appl_ptr = file->file_ptr_bytes = 0;
|
file->appl_ptr = file->file_ptr_bytes = 0;
|
||||||
for (channel = 0; channel < slave->channels; ++channel) {
|
for (channel = 0; channel < slave->channels; ++channel) {
|
||||||
snd_pcm_channel_area_t *a = &file->wbuf_areas[channel];
|
snd_pcm_channel_area_t *a = &file->wbuf_areas[channel];
|
||||||
|
|
@ -369,18 +396,6 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
|
|
||||||
{
|
|
||||||
snd_pcm_file_t *file = pcm->private_data;
|
|
||||||
if (file->wbuf) {
|
|
||||||
free(file->wbuf);
|
|
||||||
free(file->wbuf_areas);
|
|
||||||
file->wbuf = 0;
|
|
||||||
file->wbuf_areas = 0;
|
|
||||||
}
|
|
||||||
return snd_pcm_hw_free(file->slave);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
||||||
{
|
{
|
||||||
snd_pcm_file_t *file = pcm->private_data;
|
snd_pcm_file_t *file = pcm->private_data;
|
||||||
|
|
@ -389,11 +404,23 @@ static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
|
||||||
|
|
||||||
static int snd_pcm_file_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
static int snd_pcm_file_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
snd_pcm_file_t *file = pcm->private_data;
|
||||||
|
snd_pcm_t *slave = file->slave;
|
||||||
|
pcm->running_areas = slave->running_areas;
|
||||||
|
pcm->stopped_areas = slave->stopped_areas;
|
||||||
|
pcm->mmap_channels = slave->mmap_channels;
|
||||||
|
pcm->mmap_shadow = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_file_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
static int snd_pcm_file_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
snd_pcm_file_t *file = pcm->private_data;
|
||||||
|
snd_pcm_t *slave = file->slave;
|
||||||
|
pcm->mmap_channels = NULL;
|
||||||
|
pcm->running_areas = NULL;
|
||||||
|
pcm->stopped_areas = NULL;
|
||||||
|
pcm->mmap_shadow = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -423,6 +450,7 @@ static snd_pcm_ops_t snd_pcm_file_ops = {
|
||||||
.dump = snd_pcm_file_dump,
|
.dump = snd_pcm_file_dump,
|
||||||
.nonblock = snd_pcm_file_nonblock,
|
.nonblock = snd_pcm_file_nonblock,
|
||||||
.async = snd_pcm_file_async,
|
.async = snd_pcm_file_async,
|
||||||
|
.poll_revents = snd_pcm_file_poll_revents,
|
||||||
.mmap = snd_pcm_file_mmap,
|
.mmap = snd_pcm_file_mmap,
|
||||||
.munmap = snd_pcm_file_munmap,
|
.munmap = snd_pcm_file_munmap,
|
||||||
};
|
};
|
||||||
|
|
@ -512,6 +540,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
|
||||||
pcm->private_data = file;
|
pcm->private_data = file;
|
||||||
pcm->poll_fd = slave->poll_fd;
|
pcm->poll_fd = slave->poll_fd;
|
||||||
pcm->poll_events = slave->poll_events;
|
pcm->poll_events = slave->poll_events;
|
||||||
|
pcm->mmap_shadow = 1;
|
||||||
snd_pcm_link_hw_ptr(pcm, slave);
|
snd_pcm_link_hw_ptr(pcm, slave);
|
||||||
snd_pcm_link_appl_ptr(pcm, slave);
|
snd_pcm_link_appl_ptr(pcm, slave);
|
||||||
*pcmp = pcm;
|
*pcmp = pcm;
|
||||||
|
|
|
||||||
|
|
@ -200,9 +200,9 @@ struct _snd_pcm {
|
||||||
snd_pcm_rbptr_t appl;
|
snd_pcm_rbptr_t appl;
|
||||||
snd_pcm_rbptr_t hw;
|
snd_pcm_rbptr_t hw;
|
||||||
snd_pcm_uframes_t min_align;
|
snd_pcm_uframes_t min_align;
|
||||||
int mmap_rw;
|
int mmap_rw: 1,
|
||||||
int shadow_mmap;
|
mmap_shadow: 1,
|
||||||
int donot_close;
|
donot_close: 1;
|
||||||
snd_pcm_channel_info_t *mmap_channels;
|
snd_pcm_channel_info_t *mmap_channels;
|
||||||
snd_pcm_channel_area_t *running_areas;
|
snd_pcm_channel_area_t *running_areas;
|
||||||
snd_pcm_channel_area_t *stopped_areas;
|
snd_pcm_channel_area_t *stopped_areas;
|
||||||
|
|
|
||||||
|
|
@ -295,7 +295,7 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
|
||||||
err = pcm->ops->mmap(pcm);
|
err = pcm->ops->mmap(pcm);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (pcm->shadow_mmap)
|
if (pcm->mmap_shadow)
|
||||||
return 0;
|
return 0;
|
||||||
pcm->mmap_channels = calloc(pcm->channels, sizeof(pcm->mmap_channels[0]));
|
pcm->mmap_channels = calloc(pcm->channels, sizeof(pcm->mmap_channels[0]));
|
||||||
if (!pcm->mmap_channels)
|
if (!pcm->mmap_channels)
|
||||||
|
|
@ -434,7 +434,7 @@ int snd_pcm_munmap(snd_pcm_t *pcm)
|
||||||
unsigned int c;
|
unsigned int c;
|
||||||
assert(pcm);
|
assert(pcm);
|
||||||
assert(pcm->mmap_channels);
|
assert(pcm->mmap_channels);
|
||||||
if (pcm->shadow_mmap)
|
if (pcm->mmap_shadow)
|
||||||
return pcm->ops->munmap(pcm);
|
return pcm->ops->munmap(pcm);
|
||||||
for (c = 0; c < pcm->channels; ++c) {
|
for (c = 0; c < pcm->channels; ++c) {
|
||||||
snd_pcm_channel_info_t *i = &pcm->mmap_channels[c];
|
snd_pcm_channel_info_t *i = &pcm->mmap_channels[c];
|
||||||
|
|
|
||||||
|
|
@ -943,7 +943,7 @@ static int snd_pcm_plug_mmap(snd_pcm_t *pcm)
|
||||||
pcm->mmap_channels = plug->slave->mmap_channels;
|
pcm->mmap_channels = plug->slave->mmap_channels;
|
||||||
pcm->running_areas = plug->slave->running_areas;
|
pcm->running_areas = plug->slave->running_areas;
|
||||||
pcm->stopped_areas = plug->slave->stopped_areas;
|
pcm->stopped_areas = plug->slave->stopped_areas;
|
||||||
pcm->shadow_mmap = 1;
|
pcm->mmap_shadow = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -953,7 +953,7 @@ static int snd_pcm_plug_munmap(snd_pcm_t *pcm)
|
||||||
pcm->mmap_channels = NULL;
|
pcm->mmap_channels = NULL;
|
||||||
pcm->running_areas = NULL;
|
pcm->running_areas = NULL;
|
||||||
pcm->stopped_areas = NULL;
|
pcm->stopped_areas = NULL;
|
||||||
pcm->shadow_mmap = 0;
|
pcm->mmap_shadow = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue