diff options
author | Eric Laurent <elaurent@google.com> | 2021-01-19 16:45:28 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-01-19 16:45:28 +0000 |
commit | 19a5d55fb349b0a5a9f32619122ca9f05e330161 (patch) | |
tree | a15cfd3fe3330a25bfcb374d7c9ff96fbdc9a0cc | |
parent | e6c59a83007446caffbcb8aeddf9cfa9fa0fda71 (diff) | |
parent | f0ddfb0b029af9d18262aa147fa524b87cf2b7c1 (diff) | |
download | tinyalsa-19a5d55fb349b0a5a9f32619122ca9f05e330161.tar.gz |
Merge changes I22a32a3a,I7b5b5941,Ic8a1976e,I79f480bf,I5a29eb8d, ... am: a884af18d0 am: f0ddfb0b02
Original change: https://android-review.googlesource.com/c/platform/external/tinyalsa/+/1554370
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: Ib91ddba674d9f76d39c71f276197f7cd53ba64d2
-rw-r--r-- | include/tinyalsa/pcm_plugin.h | 7 | ||||
-rw-r--r-- | pcm.c | 25 | ||||
-rw-r--r-- | pcm_hw.c | 23 | ||||
-rw-r--r-- | pcm_io.h | 6 | ||||
-rw-r--r-- | pcm_plugin.c | 67 |
5 files changed, 111 insertions, 17 deletions
diff --git a/include/tinyalsa/pcm_plugin.h b/include/tinyalsa/pcm_plugin.h index 5d6f503..f1708b1 100644 --- a/include/tinyalsa/pcm_plugin.h +++ b/include/tinyalsa/pcm_plugin.h @@ -30,6 +30,8 @@ #ifndef __PCM_PLUGIN_H__ #define __PCM_PLUGIN_H__ +#include <poll.h> + #define PCM_PLUGIN_OPEN_FN(name) \ int name##_open(struct pcm_plugin **plugin, \ unsigned int card, \ @@ -63,6 +65,11 @@ struct pcm_plugin_ops { int (*drop) (struct pcm_plugin *plugin); int (*ioctl) (struct pcm_plugin *plugin, int cmd, void *arg); + void* (*mmap) (struct pcm_plugin *plugin, void *addr, size_t length, int prot, + int flags, off_t offset); + int (*munmap) (struct pcm_plugin *plugin, void *addr, size_t length); + int (*poll) (struct pcm_plugin *plugin, struct pollfd *pfd, nfds_t nfds, + int timeout); }; struct pcm_plugin_min_max { @@ -363,19 +363,19 @@ static int pcm_hw_mmap_status(struct pcm *pcm) { return 0; int page_size = sysconf(_SC_PAGE_SIZE); - pcm->mmap_status = mmap(NULL, page_size, PROT_READ, MAP_FILE | MAP_SHARED, - pcm->fd, SNDRV_PCM_MMAP_OFFSET_STATUS); + pcm->mmap_status = pcm->ops->mmap(pcm->data, NULL, page_size, PROT_READ, MAP_FILE | MAP_SHARED, + SNDRV_PCM_MMAP_OFFSET_STATUS); if (pcm->mmap_status == MAP_FAILED) pcm->mmap_status = NULL; if (!pcm->mmap_status) goto mmap_error; - pcm->mmap_control = mmap(NULL, page_size, PROT_READ | PROT_WRITE, - MAP_FILE | MAP_SHARED, pcm->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL); + pcm->mmap_control = pcm->ops->mmap(pcm->data, NULL, page_size, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, SNDRV_PCM_MMAP_OFFSET_CONTROL); if (pcm->mmap_control == MAP_FAILED) pcm->mmap_control = NULL; if (!pcm->mmap_control) { - munmap(pcm->mmap_status, page_size); + pcm->ops->munmap(pcm->data, pcm->mmap_status, page_size); pcm->mmap_status = NULL; goto mmap_error; } @@ -410,9 +410,9 @@ static void pcm_hw_munmap_status(struct pcm *pcm) { } else { int page_size = sysconf(_SC_PAGE_SIZE); if (pcm->mmap_status) - munmap(pcm->mmap_status, page_size); + pcm->ops->munmap(pcm->data, pcm->mmap_status, page_size); if (pcm->mmap_control) - munmap(pcm->mmap_control, page_size); + pcm->ops->munmap(pcm->data, pcm->mmap_control, page_size); } pcm->mmap_status = NULL; pcm->mmap_control = NULL; @@ -883,7 +883,7 @@ int pcm_close(struct pcm *pcm) if (pcm->flags & PCM_MMAP) { pcm_stop(pcm); - munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size)); + pcm->ops->munmap(pcm->data, pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size)); } if (pcm->data) @@ -981,8 +981,9 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, pcm->buffer_size = config->period_count * config->period_size; if (flags & PCM_MMAP) { - pcm->mmap_buffer = mmap(NULL, pcm_frames_to_bytes(pcm, pcm->buffer_size), - PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, pcm->fd, 0); + pcm->mmap_buffer = pcm->ops->mmap(pcm->data, NULL, + pcm_frames_to_bytes(pcm, pcm->buffer_size), + PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, 0); if (pcm->mmap_buffer == MAP_FAILED) { oops(pcm, errno, "failed to mmap buffer %d bytes\n", pcm_frames_to_bytes(pcm, pcm->buffer_size)); @@ -1058,7 +1059,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, fail: if (flags & PCM_MMAP) - munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size)); + pcm->ops->munmap(pcm->data, pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size)); fail_close: pcm->ops->close(pcm->data); pcm->data = NULL; @@ -1225,7 +1226,7 @@ int pcm_wait(struct pcm *pcm, int timeout) do { /* let's wait for avail or timeout */ - err = poll(&pfd, 1, timeout); + err = pcm->ops->poll(pcm->data, &pfd, 1, timeout); if (err < 0) return -errno; @@ -38,6 +38,7 @@ #include <poll.h> #include <sys/ioctl.h> +#include <sys/mman.h> #include <linux/ioctl.h> #include <sound/asound.h> #include <tinyalsa/asoundlib.h> @@ -74,6 +75,25 @@ static int pcm_hw_ioctl(void *data, unsigned int cmd, ...) return ioctl(hw_data->fd, cmd, arg); } +static int pcm_hw_poll(void *data __attribute__((unused)), + struct pollfd *pfd, nfds_t nfds, int timeout) +{ + return poll(pfd, nfds, timeout); +} + +static void* pcm_hw_mmap(void *data, void *addr, size_t length, int prot, + int flags, off_t offset) +{ + struct pcm_hw_data *hw_data = data; + + return mmap(addr, length, prot, flags, hw_data->fd, offset); +} + +static int pcm_hw_munmap(void *data __attribute__((unused)), void *addr, size_t length) +{ + return munmap(addr, length); +} + static int pcm_hw_open(unsigned int card, unsigned int device, unsigned int flags, void **data, __attribute__((unused)) void *node) @@ -120,4 +140,7 @@ struct pcm_ops hw_ops = { .open = pcm_hw_open, .close = pcm_hw_close, .ioctl = pcm_hw_ioctl, + .mmap = pcm_hw_mmap, + .munmap = pcm_hw_munmap, + .poll = pcm_hw_poll, }; @@ -31,11 +31,17 @@ #ifndef __PCM_H__ #define __PCM_H__ +#include <poll.h> + struct pcm_ops { int (*open) (unsigned int card, unsigned int device, unsigned int flags, void **data, void *node); void (*close) (void *data); int (*ioctl) (void *data, unsigned int cmd, ...); + void* (*mmap) (void *data, void *addr, size_t length, int prot, int flags, + off_t offset); + int (*munmap) (void *data, void *addr, size_t length); + int (*poll) (void *data, struct pollfd *pfd, nfds_t nfds, int timeout); }; #endif /* end of __PCM_H__ */ diff --git a/pcm_plugin.c b/pcm_plugin.c index 12ab34b..14c6cdb 100644 --- a/pcm_plugin.c +++ b/pcm_plugin.c @@ -510,12 +510,35 @@ static int pcm_plug_sparams(struct pcm_plug_data *plug_data, return plugin->ops->sw_params(plugin, params); } +static int convert_plugin_to_pcm_state(int plugin_state) +{ + switch (plugin_state) { + case PCM_PLUG_STATE_SETUP: + return PCM_STATE_SETUP; + case PCM_PLUG_STATE_RUNNING: + return PCM_STATE_RUNNING; + case PCM_PLUG_STATE_PREPARED: + return PCM_STATE_PREPARED; + case PCM_PLUG_STATE_OPEN: + return PCM_STATE_OPEN; + } + + return PCM_STATE_OPEN; +} + static int pcm_plug_sync_ptr(struct pcm_plug_data *plug_data, struct snd_pcm_sync_ptr *sync_ptr) { struct pcm_plugin *plugin = plug_data->plugin; + int ret = -EBADFD; + + if (plugin->state >= PCM_PLUG_STATE_SETUP) { + ret = plugin->ops->sync_ptr(plugin, sync_ptr); + if (ret == 0) + sync_ptr->s.status.state = convert_plugin_to_pcm_state(plugin->state); + } - return plugin->ops->sync_ptr(plugin, sync_ptr); + return ret; } static int pcm_plug_writei_frames(struct pcm_plug_data *plug_data, @@ -546,10 +569,10 @@ static int pcm_plug_ttstamp(struct pcm_plug_data *plug_data, { struct pcm_plugin *plugin = plug_data->plugin; - if (plugin->state != PCM_PLUG_STATE_RUNNING) + if (plugin->state >= PCM_PLUG_STATE_SETUP) + return plugin->ops->ttstamp(plugin, tstamp); + else return -EBADFD; - - return plugin->ops->ttstamp(plugin, tstamp); } static int pcm_plug_prepare(struct pcm_plug_data *plug_data) @@ -648,6 +671,37 @@ static int pcm_plug_ioctl(void *data, unsigned int cmd, ...) return ret; } +static int pcm_plug_poll(void *data, struct pollfd *pfd, nfds_t nfds, + int timeout) +{ + struct pcm_plug_data *plug_data = data; + struct pcm_plugin *plugin = plug_data->plugin; + + return plugin->ops->poll(plugin, pfd, nfds, timeout); +} + +static void* pcm_plug_mmap(void *data, void *addr, size_t length, int prot, + int flags, off_t offset) +{ + struct pcm_plug_data *plug_data = data; + struct pcm_plugin *plugin = plug_data->plugin; + + if (plugin->state != PCM_PLUG_STATE_SETUP) + return NULL; + return plugin->ops->mmap(plugin, addr, length, prot, flags, offset); +} + +static int pcm_plug_munmap(void *data, void *addr, size_t length) +{ + struct pcm_plug_data *plug_data = data; + struct pcm_plugin *plugin = plug_data->plugin; + + if (plugin->state != PCM_PLUG_STATE_SETUP) + return -EBADFD; + + return plugin->ops->munmap(plugin, addr, length); +} + static int pcm_plug_open(unsigned int card, unsigned int device, unsigned int flags, void **data, void *pcm_node) { @@ -669,7 +723,7 @@ static int pcm_plug_open(unsigned int card, unsigned int device, dl_hdl = dlopen(so_name, RTLD_NOW); if (!dl_hdl) { - fprintf(stderr, "%s: unable to open %s\n", __func__, so_name); + fprintf(stderr, "%s: unable to open %s: %s\n", __func__, so_name, dlerror()); goto err_dl_open; } else { fprintf(stderr, "%s: dlopen successful for %s\n", __func__, so_name); @@ -739,4 +793,7 @@ struct pcm_ops plug_ops = { .open = pcm_plug_open, .close = pcm_plug_close, .ioctl = pcm_plug_ioctl, + .mmap = pcm_plug_mmap, + .munmap = pcm_plug_munmap, + .poll = pcm_plug_poll, }; |