diff options
author | Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | 2012-07-29 19:46:59 -0500 |
---|---|---|
committer | David Henningsson <david.henningsson@canonical.com> | 2012-11-07 08:20:19 +0100 |
commit | 635eef998134ca34aca37b5565af91f6eb6c41cc (patch) | |
tree | 04abf99b9753c7daedd71fec86b2bea02ba38d99 | |
parent | 700cd890a91202ce42b2027abab576d16878204e (diff) |
alsa: get avail, delay, timestamps in a single kernel call
Refactor code to fetch avail, delay and timestamp values
in a single call to snd_pcm_status().
The information reported is exactly the same as before,
however it is extracted in a more atomic manner to
improve timer-based scheduling.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
-rw-r--r-- | src/modules/alsa/alsa-sink.c | 12 | ||||
-rw-r--r-- | src/modules/alsa/alsa-source.c | 12 | ||||
-rw-r--r-- | src/modules/alsa/alsa-util.c | 17 | ||||
-rw-r--r-- | src/modules/alsa/alsa-util.h | 2 |
4 files changed, 21 insertions, 22 deletions
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index d3bf76d2..eab70ef8 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -825,6 +825,7 @@ static void update_smoother(struct userdata *u) { int err; pa_usec_t now1 = 0, now2; snd_pcm_status_t *status; + snd_htimestamp_t htstamp = { 0, 0 }; snd_pcm_status_alloca(&status); @@ -833,18 +834,13 @@ static void update_smoother(struct userdata *u) { /* Let's update the time smoother */ - if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, &delay, u->hwbuf_size, &u->sink->sample_spec, FALSE)) < 0)) { + if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, status, &delay, u->hwbuf_size, &u->sink->sample_spec, FALSE)) < 0)) { pa_log_warn("Failed to query DSP status data: %s", pa_alsa_strerror(err)); return; } - if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0)) - pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err)); - else { - snd_htimestamp_t htstamp = { 0, 0 }; - snd_pcm_status_get_htstamp(status, &htstamp); - now1 = pa_timespec_load(&htstamp); - } + snd_pcm_status_get_htstamp(status, &htstamp); + now1 = pa_timespec_load(&htstamp); /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */ if (now1 <= 0) diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index d3a356ac..802b51b5 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -767,6 +767,7 @@ static void update_smoother(struct userdata *u) { int err; pa_usec_t now1 = 0, now2; snd_pcm_status_t *status; + snd_htimestamp_t htstamp = { 0, 0 }; snd_pcm_status_alloca(&status); @@ -775,18 +776,13 @@ static void update_smoother(struct userdata *u) { /* Let's update the time smoother */ - if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, &delay, u->hwbuf_size, &u->source->sample_spec, TRUE)) < 0)) { + if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, status, &delay, u->hwbuf_size, &u->source->sample_spec, TRUE)) < 0)) { pa_log_warn("Failed to get delay: %s", pa_alsa_strerror(err)); return; } - if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0)) - pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err)); - else { - snd_htimestamp_t htstamp = { 0, 0 }; - snd_pcm_status_get_htstamp(status, &htstamp); - now1 = pa_timespec_load(&htstamp); - } + snd_pcm_status_get_htstamp(status, &htstamp); + now1 = pa_timespec_load(&htstamp); /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */ if (now1 <= 0) diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index bb4e307c..4a29a9a7 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -1141,10 +1141,11 @@ snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa return n; } -int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss, pa_bool_t capture) { +int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_status_t *status, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss, + pa_bool_t capture) { ssize_t k; size_t abs_k; - int r; + int err; snd_pcm_sframes_t avail = 0; pa_assert(pcm); @@ -1154,10 +1155,16 @@ int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_si /* Some ALSA driver expose weird bugs, let's inform the user about * what is going on. We're going to get both the avail and delay values so - * that we can compare and check them for capture */ + * that we can compare and check them for capture. + * This is done with snd_pcm_status() which provides + * avail, delay and timestamp values in a single kernel call to improve + * timer-based scheduling */ - if ((r = snd_pcm_avail_delay(pcm, &avail, delay)) < 0) - return r; + if ((err = snd_pcm_status(pcm, status)) < 0) + return err; + + avail = snd_pcm_status_get_avail(status); + *delay = snd_pcm_status_get_delay(status); k = (ssize_t) *delay * (ssize_t) pa_frame_size(ss); diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index a4beed2b..236a3294 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -125,7 +125,7 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents); pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll); snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa_sample_spec *ss); -int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss, pa_bool_t capture); +int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_status_t *status, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss, pa_bool_t capture); int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames, size_t hwbuf_size, const pa_sample_spec *ss); char *pa_alsa_get_driver_name(int card); |